在非托管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位于同一目录中?
完成上述操作的一种方法是使用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的输出。