非托管c ++ .dll如何知道托管c#.dll的位置在哪里?
某些背景: 我有一个c ++ .dll导入一个类型库(.tlb)并且在一个c ++函数中,我实例化了一个指向c#.dll中函数的指针。然后,使用该指针,我可以在c ++中调用c#函数。我想知道c ++ .dll是如何知道c#.dll的位置的?此外,有更好的方法来进行这种编码吗?
.tlb是否需要与c#.dll在同一目录中?
答案 0 :(得分:4)
完成上述操作的一种方法是使用regasm命令向Microsoft Windows注册表注册C#dll文件。此命令EXE包含在Visual Studios的发行版中。该命令的示例使用如下:
regasm NameofC#DLL.dll /tlb:NameofC#DLL.tlb
在注册表中注册后,您需要使用gacutil命令将其安装到全局程序集缓存(GAC)。这也包含在Visual Studios的发行版中。该命令的示例使用如下:
gacutil / i NameofC#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创建工具和“创建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 studio中包含的tlbexp命令生成。该命令的示例使用如下:
tlbexp NameofC#DLL.dll
如果您未指定路径,则默认为以下路径:
C:\ Program Files \ Microsoft Visual Studio 9.0 \ VC
有几个地方可以解决这个问题,C#DLL调用将会失败。
此致
SeaMossDesign
答案 1 :(得分:1)
也许我错过了一些东西,但你可以创建一个自定义CLR host并从C#调用一个没有指针的方法。检查ICLRRuntimeHost::ExecuteInDefaultAppDomain。