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

C++项目中调用C#DLL的的方式

C++项目中调用C#DLL的的方式

  • 方法一:使用COM技术
  • 方法二:使用C++/CLI
  • 方法三:使用P/Invoke(适用于C#导出非托管接口)

在C++中调用C#编写的DLL,通常需要借助COM(Component Object Model)技术或者通过C++/CLI(C++托管扩展)来实现。以下是两种常见的方法:

方法一:使用COM技术

1.在C#中创建COM可见的类库
在C#项目中,确保类库项目属性中的“Make assembly COM-Visible”选项被勾选。这会为类库生成一个GUID,并将其注册为COM组件。
例如,创建一个C#类库项目MyCSharpLibrary,并添加一个类MyClass:
下面展示一些 内联代码片

using System;
using System.Runtime.InteropServices;[ComVisible(true)]
[Guid("YOUR-GUID-HERE")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMyClass
{void MyMethod();
}[ComVisible(true)]
[Guid("YOUR-CLASS-GUID-HERE")]
public class MyClass : IMyClass
{public void MyMethod(){Console.WriteLine("Hello from C#!");}
}

生成DLL后,使用regasm工具将其注册为COM组件:
下面展示一些 内联代码片

下面展示一些 内联代码片

regasm MyCSharpLibrary.dll /codebase

2.在C++中调用COM组件
在C++代码中,通过COM接口调用C#类库中的方法:
下面展示一些 内联代码片

#include <iostream>
#import "MyCSharpLibrary.tlb" // 导入类型库文件int main()
{CoInitialize(NULL); // 初始化COM库IMyClassPtr myClass(__uuidof(MyClass)); // 创建COM对象myClass->MyMethod(); // 调用方法CoUninitialize(); // 释放COM库return 0;
}

注意:需要确保C++项目中链接了ole32.lib和oleaut32.lib。

方法二:使用C++/CLI

C++/CLI是一种混合编程语言,允许在C++代码中直接使用托管代码(如C#代码)。
创建C++/CLI项目
在Visual Studio中创建一个C++/CLI项目,例如MyCppCliWrapper。
在C++/CLI中引用C# DLL
在C++/CLI项目中添加对C# DLL的引用。
创建一个托管类来封装C#类的功能:
下面展示一些 内联代码片

// MyCppCliWrapper.h
#pragma onceusing namespace System;public ref class MyCppCliWrapper
{
public:void CallCSharpMethod();
};
// MyCppCliWrapper.cpp
#include "MyCppCliWrapper.h"
#include "MyCSharpLibrary.h" // 引用C#类库void MyCppCliWrapper::CallCSharpMethod()
{MyCSharpLibrary::MyClass^ myClass = gcnew MyCSharpLibrary::MyClass();myClass->MyMethod();
}

3.在C++代码中调用C++/CLI封装
在C++代码中调用C++/CLI封装的函数:
下面展示一些 内联代码片

#include <iostream>
#include "MyCppCliWrapper.h"int main()
{MyCppCliWrapper^ wrapper = gcnew MyCppCliWrapper();wrapper->CallCSharpMethod();return 0;
}

方法三:使用P/Invoke(适用于C#导出非托管接口)

如果C# DLL中导出了非托管接口(例如通过DllImport或[UnmanagedCallersOnly]),可以直接在C++中通过函数指针调用。
在C#中导出非托管接口
使用[UnmanagedCallersOnly]属性导出方法:
下面展示一些 内联代码片

using System;
using System.Runtime.InteropServices;public class MyClass
{[UnmanagedCallersOnly(EntryPoint = "MyMethod")]public static void MyMethod(){Console.WriteLine("Hello from C#!");}
}

在C++中调用导出的函数
加载DLL并获取函数指针:
下面展示一些 内联代码片

#include <iostream>
#include <windows.h>typedef void (*MyMethodFunc)();int main()
{HMODULE hModule = LoadLibrary("MyCSharpLibrary.dll");if (hModule){MyMethodFunc myMethod = (MyMethodFunc)GetProcAddress(hModule, "MyMethod");if (myMethod){myMethod();}FreeLibrary(hModule);}return 0;
}

总结
COM技术:适合需要跨语言调用的场景,但需要额外的注册和配置。
C++/CLI:适合需要在C++中直接调用托管代码的场景,代码更简洁。
P/Invoke:适合C#导出非托管接口的场景,调用方式更接近原生C++。

http://www.lryc.cn/news/2387138.html

相关文章:

  • 咳嗽止咳药笔记250526 , 磷酸苯丙哌林 , 喷托维林 , 右美沙芬
  • vue pinia 独立维护,仓库统一导出
  • 网络的协议和标准
  • 十六进制字符转十进制算法
  • 跟Gemini学做PPT:汇报背景图寻找指南
  • java交易所,多语言,外汇,黄金,区块链,dapp类型的,支持授权,划转,挖矿(源码下载)
  • (已开源-CVPR2024) RadarDistill---NuScenes数据集Radar检测第一名
  • 【MySQL】 数据库基础数据类型
  • 中小企业AI算力如何选?【显卡租赁】VS【自建服务器】
  • OpenHarmony 4.1版本应用升级到5.0版本问题记录及解决方案
  • std::initialzer_list 与花括号{}数据列表
  • 萤石云实际视频实时接入(生产环境)
  • QT中常用的类
  • Docker系列(四):容器操作全栈技术指南 --- 从入门到生产级管控
  • poppler_path 是用于 Python 库如 pdf2image 进行 PDF 转换时
  • 鸿蒙OSUniApp 开发的多图浏览器组件#三方框架 #Uniapp
  • MongoDB 错误处理与调试完全指南:从入门到精通
  • React从基础入门到高级实战:React 核心技术 - 表单处理与验证深度指南
  • 【C++】stack,queue和priority_queue(优先级队列)
  • ubuntu中上传项目至GitHub仓库教程
  • [Java实战]Spring Boot整合达梦数据库连接池配置(三十四)
  • windows 下用yolov5 训练模型 给到opencv 使用
  • Spark集群架构解析:核心组件与Standalone、YARN模式深度对比(AM,Container,Driver,Executor)
  • Linux Kernel调试:强大的printk(二)
  • Kafka Kraft模式集群 + ssl
  • [crxjs]自己创建一个浏览器插件
  • 类的设计模式——单例、工厂以及建造者模式
  • STM32之看门狗(IWDG)
  • PyTorch实现MLP信用评分模型全流程
  • 语音识别——文本转语音