当前位置: 首页 > news >正文

C#编写DLL,其它语言可以调用

C# DLL 跨语言互操作:C++、Python、Java 调用示例

你想知道如何编写能被其他编程语言(如C++、Python、Java等)调用的C# DLL,这需要解决不同语言间的互操作(Interop)问题,核心是让C# DLL符合跨语言调用的标准。

一、核心思路:让C# DLL支持COM/非托管调用

普通C# DLL基于.NET托管代码,非.NET语言(如C++原生、Python)无法直接调用,需要通过以下两种主流方式实现跨语言调用:

  1. 方式1:将C# DLL注册为COM组件(兼容绝大多数语言:C++、VB6、Python、Java等);

  2. 方式2:通过P/Invoke封装非托管导出函数(主要适配C/C++等原生语言)。

下面优先讲解最通用的COM组件方式,再补充P/Invoke方式。

方式1:创建可注册为COM的C# DLL(通用跨语言)

步骤1:创建类库项目并配置COM兼容

  1. 打开Visual Studio,创建「类库(.NET Framework)」项目(.NET Core/.NET 5+需额外配置,推荐先用.NET Framework做兼容),命名为ComInteropDll

  2. 右键项目→「属性」→「应用程序」→「程序集信息」,勾选「使程序集COM可见」。

  3. 右键项目→「属性」→「生成」,勾选「为COM互操作注册」(仅开发环境需要,发布时手动注册)。

步骤2:编写COM兼容的C#代码

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); } }

步骤3:编译并注册COM组件

  1. 按F6编译项目,生成ComInteropDll.dllComInteropDll.tlb(类型库文件,供其他语言识别)。

  2. 注册COM组件(管理员权限运行CMD):

    # 替换为你的DLL路径(Release版建议用Release目录) regasm /codebase "C:\ComInteropDll\bin\Debug\ComInteropDll.dll"
    1. 卸载COM组件(如需):regasm /u "你的DLL路径"

步骤4:不同语言调用该COM DLL示例

示例1:Python调用(使用pywin32库)
# 先安装依赖: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
示例2:C++原生调用(使用COM接口)
#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; }

方式2:P/Invoke导出非托管函数(适配C/C++)

如果仅需给C/C++调用,可通过DllExport库直接导出非托管函数(C#原生不支持直接导出函数,需第三方库)。

步骤1:安装DllExport库

在NuGet包管理器中安装:UnmanagedExports(注意:仅支持.NET Framework)。

步骤2:编写导出函数的C#代码

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); } } }

步骤3:C++调用该DLL

#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; }

关键注意事项

  1. 数据类型兼容:跨语言调用时,优先使用基础数据类型(int、double、string),避免复杂自定义类型;字符串需注意编码(ANSI/UTF-8/UTF-16)。

  2. 框架选择

    1. .NET Framework:对COM/P/Invoke支持最好,兼容老语言;

    2. .NET Core/.NET 5+:需用ComHostNativeAOT编译为原生DLL,步骤更复杂。

  3. 错误处理:跨语言调用时,C#中的异常无法直接传递给非托管语言,建议返回错误码而非抛出异常。

  4. 64位/32位适配:编译DLL和调用程序时,需保持位数一致(均为x86或x64),否则会调用失败。

总结

  1. 通用跨语言方案:将C# DLL注册为COM组件,适配Python、Java、C++等绝大多数语言,核心是通过ComVisibleGuid暴露接口,并注册COM。

  2. C/C++专属方案:使用UnmanagedExports库导出非托管函数,通过P/Invoke调用,更轻量但仅适配C/C++。

  3. 核心要点:保持数据类型简单、位数一致、处理好内存释放(尤其是字符串),是跨语言调用的关键。

http://www.jsqmd.com/news/420550/

相关文章:

  • 含光伏的储能选址定容模型 14节点 程序采用改进粒子群算法,对分析14节点配网系统中的储能选址...
  • 2026年精选工单系统推荐,国内优质厂商及好用的工单系统汇总 - 品牌2025
  • 你以为的“黑客”VS真正的网络安全:过来人告诉你自学应学什么
  • 2026垫路钢板出租企业推荐,满足多样需求,铺路钢板出租/走道板租赁/工程铺路钢板出租,垫路钢板出租厂商怎么选择 - 品牌推荐师
  • springMVC-HTTP消息转换器与文件上传、下载、异常处理
  • AI_新媒体课程
  • 毕业论文神器!继续教育专属AI论文网站 —— 千笔
  • 2026年支持方言智能应答电话语音机器人厂商优选(精选5家推荐) - 品牌2025
  • 2026年中子剂量率仪知名厂家与选购指南 - 品牌推荐大师1
  • 从入门到精通:OpenCV人脸识别与表情检测全流程实战指南
  • 2026年精选推荐!高接通率+支持CRM对接电话语音机器人厂商优选 - 品牌2025
  • 2026年客服系统厂商推荐,智能应答+售后支持+订单对接全覆盖 - 品牌2025
  • 大模型AI算法高薪职业,风口,但是一定是对所有人的风口吗
  • 2026年全球机器人末端执行器加工推荐:复杂连杆机构精密制造厂家深度评估 - 余文22
  • 2026年郭氏正骨哪家强?这些选择准没错,郭氏正骨,郭氏正骨直销厂家哪个好 - 品牌推荐师
  • 2026年优质客服系统厂商精选,含工单管理、话术库搭建及免费试用 - 品牌2025
  • 2026年2月液压货梯知名厂家推荐,安全认证与市场口碑 - 品牌鉴赏师
  • 2026广东水产动保公司精选推荐榜:精博生物专注水产动保改底产品、调水产品、净水产品、杀虫产品、调代谢产品、杀螺产品,除蓝藻产品、解毒产品,打造绿色底质管理解决方案 - 海棠依旧大
  • 翱翔教务功能加强
  • 业内人士分享:挑选高密度硅酸钙管托厂家的核心要素,铝行业精炼用热鼎盘,高密度硅酸钙管托生产厂家推荐排行榜单 - 品牌推荐师
  • 2026年天津发电机出租厂家推荐:发电机租赁/大型发电机出租/静音发电机出租/柴油发电机出租/ups应急电源出租厂家选择指南 - 海棠依旧大
  • 2026中小学心理健康管理平台深度评测:AI赋能心育,守护校园成长 - 健成星云
  • 2026年2月瞧瞧有哪些热门污水处理设备企业,酸碱中和实验室污水设备/PP棉滤芯,污水处理设备实力厂家哪家强 - 品牌推荐师
  • 聚焦2026年2月!纸箱生产厂家推荐TOP名单,彩印包装/纸盒/工业纸箱/纸箱/农产品纸箱/工业纸盒,纸箱工厂哪家好 - 品牌推荐师
  • 第四届语言与文化传播国际学术会议(ICLCC 2026)
  • 前端 Vue3 + 后端 Flask + YOLOv11 检测模型 + DeepSeek AI 融合YOLO目标检测模型+Deepseek大语言模型 基于多尺度特征融合融合的道路缺陷检测
  • 拒绝踩坑!旋涡高压鼓风机知名品牌推荐,教你避开贴牌陷阱 - 品牌推荐大师
  • CMake 是什么?从编译器到构建系统的完整认知(C++ 工程入门第一课)
  • 全国讲抖音落地的老师是哪一位,铭泽国际性价比高 - 工业设备
  • 电缆沟积水监测自动告警方案