21人参与 • 2026-03-02 • Asp.net
你想知道如何编写能被其他编程语言(如c++、python、java等)调用的c# dll,这需要解决不同语言间的互操作(interop)问题,核心是让c# dll符合跨语言调用的标准。
普通c# dll基于.net托管代码,非.net语言(如c++原生、python)无法直接调用,需要通过以下两种主流方式实现跨语言调用:
下面优先讲解最通用的com组件方式,再补充p/invoke方式。
cominteropdll。com要求必须通过接口 暴露方法,且需要给接口/类添加guid(唯一标识),示例代码如下:
using system;
using system.runtime.interopservices;
// 1. 为接口添加唯一guid(可通过vs工具生成:工具→创建guid→选注册表格式,去掉{})
[guid("12345678-1234-1234-1234-1234567890ab")]
// 2. 标记为com可见的接口
[comvisible(true)]
public interface icalculator
{
// com接口方法不能有重载,参数/返回值尽量用基础类型(int、string、double等)
int add(int a, int b);
string reversestring(string input);
}
// 3. 为实现类添加唯一guid
[guid("87654321-4321-4321-4321-ba0987654321")]
[comvisible(true)]
public class calculator : icalculator
{
public int add(int a, int b)
{
return a + b;
}
public string reversestring(string input)
{
if (string.isnullorempty(input))
throw new argumentnullexception(nameof(input));
char[] arr = input.tochararray();
array.reverse(arr);
return new string(arr);
}
}按f6编译项目,生成cominteropdll.dll和cominteropdll.tlb(类型库文件,供其他语言识别)。
注册com组件(管理员权限运行cmd):
# 替换为你的dll路径(release版建议用release目录) regasm /codebase "c:\cominteropdll\bin\debug\cominteropdll.dll"
卸载com组件(如需):regasm /u "你的dll路径"
# 先安装依赖:pip install pywin32
import win32com.client
# 创建com对象(参数是接口/类的progid,或直接用guid)
# 方式1:用类名(需确保项目属性中配置了progid,或手动指定)
calculator = win32com.client.dispatch("cominteropdll.calculator")
# 调用方法
sum_result = calculator.add(10, 25)
reverse_result = calculator.reversestring("python call c# dll")
print(f"两数之和:{sum_result}") # 输出:35
print(f"反转字符串:{reverse_result}") # 输出:lld #c llac nohtyp#include <iostream>
#include <windows.h>
// 导入类型库(替换为你的tlb文件路径)
#import "c:\cominteropdll\bin\debug\cominteropdll.tlb" no_namespace
int main()
{
// 初始化com库
coinitialize(null);
// 创建com对象
icalculator* pcalculator = null;
hresult hr = cocreateinstance(
__uuidof(calculator), // 类的guid
null,
clsctx_inproc_server,
__uuidof(icalculator), // 接口的guid
(void**)&pcalculator
);
if (succeeded(hr))
{
// 调用方法
int sum = 0;
pcalculator->add(100, 200, &sum);
bstr input = sysallocstring(l"c++ call c# com dll");
bstr reversed = null;
pcalculator->reversestring(input, &reversed);
// 输出结果
std::cout << "sum: " << sum << std::endl; // 输出:300
wprintf(l"reversed: %s\n", reversed); // 输出:lld moc #c llac ++c
// 释放资源
sysfreestring(input);
sysfreestring(reversed);
pcalculator->release();
}
// 释放com库
couninitialize();
return 0;
}如果仅需给c/c++调用,可通过dllexport库直接导出非托管函数(c#原生不支持直接导出函数,需第三方库)。
在nuget包管理器中安装:unmanagedexports(注意:仅支持.net framework)。
using system;
using system.runtime.interopservices;
using rgiesecke.dllexport;
namespace pinvokedll
{
public class myexports
{
// 导出add函数,供c/c++调用
[dllexport("add", callingconvention = callingconvention.cdecl)]
public static int add(int a, int b)
{
return a + b;
}
// 导出反转字符串函数(注意字符编码适配)
[dllexport("reversestring", callingconvention = callingconvention.cdecl)]
public static intptr reversestring([marshalas(unmanagedtype.lpstr)] string input)
{
if (string.isnullorempty(input))
return intptr.zero;
char[] arr = input.tochararray();
array.reverse(arr);
string result = new string(arr);
// 分配非托管内存并返回(调用方需释放)
return marshal.stringtohglobalansi(result);
}
// 提供释放内存的函数,供调用方使用
[dllexport("freestring", callingconvention = callingconvention.cdecl)]
public static void freestring(intptr ptr)
{
if (ptr != intptr.zero)
marshal.freehglobal(ptr);
}
}
}#include <iostream>
#include <windows.h>
// 声明导入的函数
extern "c" __declspec(dllimport) int add(int a, int b);
extern "c" __declspec(dllimport) char* reversestring(const char* input);
extern "c" __declspec(dllimport) void freestring(char* ptr);
int main()
{
// 调用add函数
int sum = add(5, 8);
std::cout << "add result: " << sum << std::endl; // 输出:13
// 调用reversestring函数
char* reversed = reversestring("hello c++");
std::cout << "reversed: " << reversed << std::endl; // 输出:++c olleh
freestring(reversed); // 释放内存
return 0;
}comhost或nativeaot编译为原生dll,步骤更复杂。comvisible和guid暴露接口,并注册com。unmanagedexports库导出非托管函数,通过p/invoke调用,更轻量但仅适配c/c++。以上就是c# dll跨语言调用的两种实现方法的详细内容,更多关于c# dll跨语言调用的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论