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

相关推荐
敲代码的瓦龙11 分钟前
C++?继承!!!
c语言·开发语言·c++·windows·后端·算法
恒者走天下1 小时前
让学习回归到技术上来(技术 !=== 死记硬背)
c++
linux开发之路1 小时前
【备战秋招】C++音视频开发经典面试题整理
c++·ffmpeg·音视频·rtmp·音视频编解码
小吴同学·2 小时前
OPC Client第5讲(wxwidgets):初始界面的事件处理;按照配置文件初始化界面的内容
c++·wxwidgets
虾球xz3 小时前
游戏引擎学习第314天:将精灵拆分成多个层
linux·c++·学习·游戏引擎
会开花的二叉树4 小时前
vector的实现
数据结构·c++·算法·stl
序属秋秋秋4 小时前
《数据结构初阶》【番外篇:快速排序的前世今生】
c语言·数据结构·c++·笔记·leetcode·排序算法
CodeWithMe4 小时前
【C/C++】红黑树学习笔记
c语言·c++·学习
天赐细莲4 小时前
(C++17) 未捕获异常 uncaught_exceptions
开发语言·c++
Despacito0o6 小时前
C++面向对象编程实战:继承与派生全解析
开发语言·c++