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