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

相关推荐
汉克老师6 小时前
GESP2026年9月认证C++六级( 第三部分编程题(1、数组划分))精讲
c++·gesp·小学生·学c++编程
千里码aicood6 小时前
基于PLC与机器视觉的智能分拣控制系统设计
c++·自动化·plc
漂流瓶jz6 小时前
UVA-1442 洞穴 题解答案代码 算法竞赛入门经典第二版
c++·算法·题解·aoapc·算法竞赛入门经典·uva
朽棘不雕7 小时前
进一步了解模板
c++
汉克老师10 小时前
CSP-J 2026 初赛试题解析(第一部分:选择题(8-15))精讲
c++·csp-j·小学生·学c++编程
wabs66610 小时前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
风合星语11 小时前
2026 ROS 2 Lyrical C++ 入门(五):Action 实战——任务反馈、取消与超时处理
c++·机器人·ros2·异步编程·lyrical
91刘仁德12 小时前
C++ 继承和多态 设计模式
c语言·c++·笔记
库玛西12 小时前
哈夫曼树与前缀编码:数据压缩的贪心核心
c语言·c++·笔记·考研
别动我齐刘海12 小时前
ROS2 Jazzy + C++ 实战路线——进阶学习3
c++·人工智能·vscode·python·算法·机器学习·机器人