C++项目中调用C#DLL的的方式
在C++中调用C#编写的DLL,通常需要借助COM(Component Object Model)技术或者通过C++/CLI(C++托管扩展)来实现。以下是两种常见的方法:
方法一:使用COM技术
1.在C#中创建COM可见的类库
在C#项目中,确保类库项目属性中的"Make assembly COM-Visible"选项被勾选。这会为类库生成一个GUID,并将其注册为COM组件。
例如,创建一个C#类库项目MyCSharpLibrary,并添加一个类MyClass:
下面展示一些 内联代码片
。
javascript
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组件:
下面展示一些 内联代码片
。
下面展示一些 内联代码片
。
javascript
regasm MyCSharpLibrary.dll /codebase
2.在C++中调用COM组件
在C++代码中,通过COM接口调用C#类库中的方法:
下面展示一些 内联代码片
。
javascript
#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#类的功能:
下面展示一些 内联代码片
。
javascript
// MyCppCliWrapper.h
#pragma once
using 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封装的函数:
下面展示一些 内联代码片
。
javascript
#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]属性导出方法:
下面展示一些 内联代码片
。
javascript
using System;
using System.Runtime.InteropServices;
public class MyClass
{
[UnmanagedCallersOnly(EntryPoint = "MyMethod")]
public static void MyMethod()
{
Console.WriteLine("Hello from C#!");
}
}
在C++中调用导出的函数
加载DLL并获取函数指针:
下面展示一些 内联代码片
。
javascript
#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++。