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

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

相关推荐
小何好运暴富开心幸福4 分钟前
分层架构的C++高并发内存池性能优化
c++·性能优化·架构
汉克老师35 分钟前
GESP2025年6月认证C++三级( 第三部分编程题(1)奇偶校验)
c++·gesp三级·gesp3级
教练、我想打篮球1 小时前
68 指针的减法操作
c++·c·struct
Mr_Xuhhh1 小时前
QWidget的属性
java·数据库·c++·qt·系统架构
sun0077001 小时前
C++实现二叉树左右子树交换算法
开发语言·c++·算法
404未精通的狗2 小时前
(C++)STL:list认识与使用全解析
开发语言·c++·list
mit6.8242 小时前
youtube图论
c++·算法
海棠玛卡3 小时前
string模拟实现
c++
Murphy_lx3 小时前
较为深入的了解c++中的string类(2)
java·c++·算法
J心流4 小时前
Vscode中使用C++代码进行debug
c++·ide·vscode