C#封装动态库,提供给C++调用

本文详细介绍了如何在C#中创建并封装DLL为COM组件,包括设置 ComVisible、注册COM组件以及使用VC++调用C# DLL的方法。通过实例展示了如何在C++中通过头文件和源文件进一步封装C# DLL的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1, 首先封装一个C# Dll, 即创建工程为C#类库;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace MyCharpDll
{
    [ComVisible(true)]
    [Guid("0CE96C54-CC5F-47A6-BD21-C2635CEDC2D8")]
    public interface IMyCSharp    // 接口
    {
        [DispId(1)]
        string CombinString(string str1, string str2, out string outstr);
    }

    [ComVisible(true)]
    [Guid("56209E46-A605-492F-AA50-9D6608116181")]
    [ClassInterface(ClassInterfaceType.None)]
    public class MyCSharp : IMyCSharp // 实现类继承接口
    {
        public string CombinString(string str1, string str2, out string outstr)
        {
            outstr = str1 + str2;
            return outstr;
        }
    }
}

1) 工程->属性->应用程序->程序集信息...  弹出对话框, 勾选 "使程序集COM可见";
2) 工程->属性->生成  勾选 "为COM互操作注册"; (在其他机器上运行, 则要手动将dll注册为COM)
(3) 在这里我们通过regasm.exe生成注册表文件供使用者将dll注册为
COM组件(其实就是把GUID导入注册表)。
脚本文件如下:
regasm E:\UnmanagecodeCallManagecode\CalcClass\CalcClass\bin\Debug\CalcClass.dll
regasm E:\UnmanagecodeCallManagecode\CalcClass\CalcClass\bin\Debug\CalcClass.dll /tlb: CalcClass.tlb
regasm E:\UnmanagecodeCallManagecode\CalcClass\CalcClass\bin\Debug\CalcClass.dll /regfile: CalcClass.reg
注意使用的regasm.exe版本与开发dll所使用的.NET Framework版本最好保持一致。
运行该脚本生成CalcClass.reg文件。在其他机器上运行该文件,即可注册该COM组件,才能正常使用

注册DLLD脚本
@echo off
@echo on
RegAsm.exe  LanJiaoSharpDll.dll
pause

注销DLL脚本
@echo off
@echo on
RegAsm.exe  LanJiaoSharpDll.dll /u
pause


2, VC++调用C# Dll

#include <iostream>
#include <string.h>
#import "MyCharpDll.tlb"
using namespace std;
using namespace MyCharpDll;

void main()
{
    CoInitialize(NULL);
    IMyCSharpPtr myCSharpPtr;
    myCSharpPtr.CreateInstance(__uuidof(MyCSharp));
    if (myCSharpPtr != NULL)
    {
        char *pStr1 = "你好--";
        char* pStr2 = "欢迎光临";
        char szOut[256];
        BSTR temp;
        memset(szOut, 0, sizeof(szOut));
        myCSharpPtr->CombinString(_bstr_t(pStr1), _bstr_t(pStr2), &temp);
       char* pchar = _com_util::ConvertBSTRToString(temp); 
        strcpy_s(szOut, sizeof(szOut), pchar );
        delete[] pchar;  // 否则内存泄露
        cout << szOut << endl;
        myCSharpPtr.Release();
    }
    else
        cout << "创建接口失败" << endl;
    CoUninitialize();
}

3, VC对C# Dll再次封装

头文件:
#define CSharpDll_Export
#ifdef CSharpDll_Export
#define CSharpDllApi    __declspec(dllexport)
#else
#define CSharpDllApi    __declspec(dllimport)
#endif

extern "C" CSharpDllApi bool CombinString(char* pStr1, char* pStr2, char* pOut);

源文件:

#include "CSharpDll.h"
#include <string.h>
#import "MyCharpDll.tlb"
using namespace MyCharpDll;

bool CombinString(char* pStr1, char* pStr2, char* pOut)
{
    bool bRet = false;
    CoInitialize(NULL);
    IMyCSharpPtr myCSharpPtr;
    myCSharpPtr.CreateInstance(__uuidof(MyCSharp));
    if (myCSharpPtr != NULL)
    {
        BSTR temp;
        myCSharpPtr->CombinString(_bstr_t(pStr1), _bstr_t(pStr2), &temp);
        strcpy(pOut, _com_util::ConvertBSTRToString(temp));
        myCSharpPtr.Release();
        bRet = true;
    }
    else
        bRet = false;
    CoUninitialize();
    return bRet;
}


4, 外部调用

#include <stdio.h>
#include <STRING.H>
#include "CSharpDll.h"
#pragma comment(lib, "CSharpDll.lib")  // 这时候只需 CSharpDll.dll 文件, 因为C# DLL已经注册为COM

void main()
{
    char* pStr1 = "这是CSharp编写的DLL ";
    char* pStr2 = "该DLL提供了一个字符创拼接函数";
    char szOut[256];
    memset(szOut, 0, sizeof(szOut));
    if ( CombinString(pStr1, pStr2, szOut) )
    {
        printf("调用成功: %s\n", szOut);
    }
    else
        printf("调用失败\n");
    getchar();
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值