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

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++。

相关文章:

  • OpenLayers加载GeoJSON数据
  • 基于Android的个人健康管理系统APP
  • 第7章 C控制语句:分支和跳转
  • TCP协议原理与Java编程实战:从连接建立到断开的完整解析
  • C++ 模板函数深度指南
  • 深入解析Spring Boot与Kafka集成:构建高效消息驱动应用
  • sass三大循环语法
  • 嵌入式开发学习日志(linux系统编程--进程(2))Day28
  • 解决 iTerm2 中 nvm 不生效的问题(Mac 环境)
  • 基于树莓派的贪吃蛇游戏机
  • 【C/C++】基于 Docker 容器运行的 Kafka + C++ 练手项目
  • Kafka自定义分区策略实战避坑指南
  • Web攻防-SQL注入数据格式参数类型JSONXML编码加密符号闭合
  • pg库分表操作步骤- PostgreSQL 分区表
  • 限流系列:sentinel
  • 边缘AI:在物联网设备上实现智能处理
  • Webpack和Vite构建工具有什么区别?各自的优缺点是什么
  • 【论文解读】STaR:不用人类思维链指导,模型可以自我进化!
  • ChatGPT与认知科学:人机协同的未来图景
  • 云原生微服务devops项目管理英文表述详解
  • 做网站被骗/长春网站建设技术支持
  • 微信小程序开发介绍/seo网站优化推荐
  • 室内设计平面图尺寸/苏州百度快速排名优化
  • 网站素材图/互联网营销课程体系
  • 如何建立网站是什么/码迷seo
  • 做网站建设业务/重庆网站建设外包