繁体   English   中英

如何链接到C ++ / Cli混合模式dll中的本机类

[英]How do I link to a native class in a C++/Cli mixed-mode dll

我有以下设置:

  • CSharp.dll,一个C#dll
  • CppCli.dll,混合模式C ++ / Cli dll。
  • Native.dll,一个原生的C ++ DLL。

本机项目声明

class Native
{
public:
    virtual void Add(int a);
};

这是在混合模式项目中实现的:

class Mixed : public Native
{
public:
    virtual void Add(int a);
    ICSharpInterface^ MakeManaged();  
};

由于基类是在Native中定义的,我可以将我的实现传递给native中的其他代码。 但现在我想测试这个课程。

如果我使用#pragma make_public(Mixed); 它只会使一个结构公共,没有任何外部可见的功能。

如果我尝试从另一个混合模式dll链接到混合模式dll,我会收到链接器错误,因为它是本机类,而混合模式dll不会生成链接的.lib。

如果我尝试使用__declspec(dllexport)类,Visual Studio会抱怨,因为该接口公开了托管内容。

所以我的问题是:

如何在我的测试中实例化(链接到)这个类? 我会很高兴任何解决方案显示如何创建一个我可以调用其公共接口的实例,无论是从C ++,C ++ / Cli还是从C#开始。

您错过了一个重要的步骤,您尚未考虑本机程序如何创建Mixed对象的实例。 这是非常重要的,它确实需要加载和初始化CLR,以便它可以执行托管代码。 请记住,客户端代码不会自动执行此操作,它不知道有关CLR的bean,它只知道Native.dll。 完成此操作有三种基本方法:

  • 您可以将托管类公开为COM对象,这与[ComVisible]属性非常简单。 可以直接从C#执行,您不需要C ++ / CLI包装器。 通常的缺点是客户端代码必须使用COM来实例化对象并对其进行调用,而不是程序员喜欢编写的代码。
  • 您可以自己托管CLR,这是最有效,最灵活的解决方案。 这篇杂志文章给出了一个介绍,请注意它已过时。
  • C ++ / CLI编译器为您提供了一种为您提供可以执行托管代码的非托管导出函数的方法。 它会自动生成一个存根,如果需要,可以加载和初始化CLR。

关注最后一个子弹,因为这是你可能喜欢的,这里你需要的是一个工厂函数 ,它创建一个Mixed类的实例并将一个Native *返回给调用者。 所以它可以调用ptr-> Add()并调用Mixed :: Add()。 这看起来像这样:

extern "C" __declspec(dllexport)
Native* CreateObject() {
    return new Mixed;
}

还可以获取您可以在本机项目中链接的导入.lib。 要注意缺点,它们很重要。 它不是很快,因为存根必须检查CLR是否已初始化并进行本机到管理的转换。 错误报告非常糟糕,因为您没有合适的方法来诊断C#代码中引发的异常。 内存管理是一个问题,调用者必须能够成功销毁返回的对象,这需要所有模块使用完全相同的CRT。 COM解决的问题类型。

通过使用IL重写器,C#中也可以使用完全相同的技术。 Gieseke的非托管导出模板很受欢迎。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM