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

相关推荐
大鹏的NLP博客29 分钟前
C++ 内存安全的未来:从 Safety Profiles 到 Safe C++
c++·内存安全
程序员zgh39 分钟前
C++ erase() 函数用法
c语言·开发语言·c++·学习
All for pursuit.1 小时前
【并查集-2】399.除法求值
数据结构·c++·算法·leetcode
程序喵大人3 小时前
【C++入门】编译链接模型 - 05 ODR 为什么会让重复定义变成工程炸点
开发语言·c++·编译链接·odr
汉克老师3 小时前
CSP-S 2026 初赛试题解析(第一部分:选择题(8-15))精讲
c++·csp-s·小学生·学c++编程
_wyt0014 小时前
洛谷 P10112 [GESP202312 八级] 奖品分配 题解
c++·数学·gesp·八级
朝朝辞暮i4 小时前
C++ 第 33 课:事件循环——spin() 到底在干什么
开发语言·c++·算法
殷色玫瑰4 小时前
AVL树:从平衡因子到四种旋转的完整实现
c语言·数据结构·c++·算法·visualstudio
进化中的刀盾兽5 小时前
从零实现 C++ AI 大模型接入 SDK(九):LLMManager 统一模型管理与请求路由
c++
会周易的程序员5 小时前
STVM OSAL 层架构设计文档
c++·物联网·嵌入式·虚拟机·iot·软plc·iec61131