在非托管c++dll中使用托管c#dll

本文关键字:c#dll c++dll | 更新日期: 2023-09-27 17:57:34

非托管c++.dll如何知道托管c#.dll的位置?

一些上下文:我有一个导入类型库(.tlb)的c++.dll,在其中一个c++函数中,我实例化了一个指向c#.dll中函数的指针。然后,使用该指针,我可以调用c++中的c#函数。我想知道c++.dll是如何知道c#.dll在哪里的?此外,有没有更好的方法来进行这种类型的编码?

.tlb是否需要与c#.dll位于同一目录中?

在非托管c++dll中使用托管c#dll

完成上述操作的一种方法是使用regasm命令向Microsoft Windows注册表注册C#dll文件。此命令EXE包含在Visual Studio的发行版中。命令的使用示例如下:

regasm名称C#DLL.DLL/tlb:C#DLL.tlb 的名称

在注册表中注册后,需要使用gautil命令将其安装到全局程序集缓存(GAC)中。这也包括在Visual Studio的发行版中。命令的使用示例如下:

gautil/i C#DLL.DLL 的名称

一旦这些步骤完成,您的C++代码将能够找到C#dll,假设您的dll文件的构造类似于以下内容:

[C#]

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace MyNameSpace
{
    /// <summary>
    /// Interface for C++ DLL. This exposes the functions used inside the dll
    /// Make sure the return types, function names, and argument types match the class
    /// </summary>
    [ComVisible(true)]
    [Guid("CBA208F2-E43B-4958-97C7-C24EA5A213DE")]
    public interface IMyClass
    {
        int Function1();
        int Function2();
    }
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("579091E6-83A1-4aa5-89A7-F432AB2A57E3")]
    [ComVisible(true)]
    public class MyClass : IMyClass
    {
        public MyClass()
        {
            //Constructor
        }
       public int Function1()
        {
            //Do something in C#
            return an integer;
        }
        public int Function2()
        {
            //Do something else in C#
            return an integer;
        }
    }//End Class MyClass
}//End namespace MyNameSpace

无论你在哪里看到一个正在使用的GUID,这是一个随机生成的全局标识符,用于识别你的C#代码。此数字可以使用Visual Studio提供的GUID创建工具在"工具菜单"answers"创建GUID"选项下随机生成。选择注册表格式,然后按"新建GUID"。然后只需按复制并粘贴到GUID需要的位置(删除括号!)

[C++]

#include <windows.h>
#include "stdafx.h"
#include <cstdlib>
#pragma warning (disable: 4278)
#import <mscorlib.tlb> raw_interfaces_only
#include <stdio.h>
//This path needs to be valid at compile time. The file does not need to be there in runtime when using the DLL after compile.
#import "C:''...''NameofC#DLL.tlb" no_namespace named_guids
extern "C" _declspec(dllexport) int _Function1()
{   
        int result = 0;
    IMyClass *CSharpInterface = NULL;
    //Open interface to C#
    CoInitialize(NULL);
    HRESULT hr = CoCreateInstance(CLSID_MyClass, NULL, CLSCTX_INPROC_SERVER,
                                  IID_IMyClass, reinterpret_cast<void**>(&CSharpInterface));
    //Call Function1 C# method
    result = CSharpInterface->Function1();
    //Close interface
    CoUninitialize();
    //Return result
    return result;
}

编译时所需的TLB文件可以使用visualstudios附带的tlbexp命令生成。命令的使用示例如下:

tlbexp C#DLL.DLL 名称

如果您没有指定路径,它将默认为以下路径:

C: ''Program Files''Microsoft Visual Studio 9.0''VC

有几个地方你可以把它搞砸,C#DLL调用就会失败。

问候,

SeaMossDesign

也许我遗漏了一些东西,但您可以创建一个自定义CLR主机,并在没有指针的情况下从C#调用一个方法。检查ICLRuntimeHost::ExecuteInDefaultAppDomain的输出。