在未管理的C++ DLL中使用托管的C# DLL

4
一个未管理的c++ .dll如何知道托管的c# .dll的位置?
一些背景: 我有一个c++ .dll,它导入了一个类型库(.tlb),在其中一个c++函数内,我实例化了指向c# .dll内部函数的指针。然后,使用该指针,我可以在c++中调用c#函数。我想知道c++ .dll如何知道c# .dll在哪里?此外,是否有更好的方法来进行这种类型的编程?
.tlb需要与c# .dll位于同一目录中吗?
2个回答

4
一种实现以上目标的方法是使用regasm命令将C# dll文件在Microsoft Windows注册表中注册。该命令EXE随Visual Studios发行。以下是命令的示例用法:
regasm NameofC#DLL.dll /tlb:NameofC#DLL.tlb
注册到注册表后,您需要使用gacutil命令将其安装到全局程序集缓存(GAC)。这也包含在Visual Studios的发行版中。以下是命令的示例用法:
gacutil /i NameofC#DLL.dll
完成这些步骤后,假设您的DLL文件构造类似于以下内容,您的C++代码将能够找到C# 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 Studios提供的GUID创建工具通过“工具菜单”和“创建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文件可以使用visual studios附带的tlbexp命令生成。以下是该命令的示例用法:

tlbexp NameofC#DLL.dll

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

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

有几个地方可能会出错,导致C# DLL调用失败。

敬礼,

SeaMossDesign


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接