使用非托管接口进行托管

时间:2011-09-11 15:33:08

标签: c++ clr managed-c++

我有一个非托管库,暴露了一些接口。用户可以使用自定义实现实现接口并将其粘贴到库中。

我想为这个库提供托管包装器。 使用托管接口包装非托管接口很容易。但在我的情况下,我想支持各种接口的用户实现,这意味着我需要采用接口的托管实现,并在将其发送到库的非托管部分的深度之前使用其非托管对应物进行包装。

我尝试过类似的事情:

class UnmanagedWrapper {
DoSomething() {m_clr.DoSomething();}
IManaged^ m_clr;
}

但是我不能在非托管类中拥有托管成员,编译器理所当然地声称。

我可以在这里做任何优雅的事吗?

3 个答案:

答案 0 :(得分:0)

当一个库不受管理且托管语言使用这些库时,以下是有关解决方法的一些相关信息。

此信息的上下文是在Visual Studio中使用GoogleTest的一种方式:

Getting started with Google C++ Testing Framework

  

Visual C ++用户的重要说明如果您将测试放入   库和你的main()函数在不同的库中或在你的库中   .exe文件,那些测试不会运行。原因是Visual中的一个错误   C ++。定义测试时,Google Test会创建某些静态   对象注册它们。这些对象未引用   其他地方,但他们的建设者仍然应该运行。什么时候   Visual C ++链接器发现库中没有引用任何内容   它把图书馆扔出去的其他地方。你必须参考你的   来自主程序的测试库,用于保持链接器   丢弃它。这是怎么做的。在您的库代码中的某个地方   声明一个函数:

     

__declspec (dllexport) int PullInMyLibrary() { return 0; }

     

如果你把测试放在一个静态库(而不是DLL)中,那么__declspec(dllexport)就是

     

不是必需的。现在,在您的主程序中,编写一个调用的代码   那个功能:

   int PullInMyLibrary(); 
   static int dummy = PullInMyLibrary();
     

这会   保持你的测试参考,并让他们自己注册   启动。

     

此外,如果您在静态库中定义测试,请添加   / OPT:NOREF到您的主程序链接器选项。如果您使用MSVC ++ IDE,   转到.exe项目属性/配置   属性/链接器/优化并将参考设置设置为保持   未引用数据(/ OPT:NOREF)。这将保持Visual C ++链接器   丢弃您的测试从最终产生的个别符号   可执行文件。

     

但还有一个陷阱。如果您使用Google Test作为静态   库(这是在gtest.vcproj中定义的方式)你的测试必须   也驻留在静态库中。如果你必须将它们放在DLL中,   您必须更改Google Test以构建DLL。除此以外   您的测试将无法正常运行或根本无法运行。一般   这里的结论是:让你的生活更轻松 - 不要写你的考试   库!

答案 1 :(得分:0)

也许 gcroot<> 就是您想要的:

class UnmanagedWrapper {
    DoSomething() {m_clr.DoSomething();}
    gcroot<IManaged^> m_clr;
}

答案 2 :(得分:0)

您需要将非托管dll导入C#.Net应用。我的示例返回指向结构的指针,但您可以提供应用程序所需的任何其他返回类型。请务必使用dumpbin.exe / EXPORTS从dll获取整个函数/ EntryPoint名称。这是我的全班:

Observable.FromEventPattern(ev => Appearing += ev, ev => Appearing -= ev)
            .Select(e => Unit.Default)
            .Take(1)
            .InvokeCommand(ViewModel.InitialCollectionLoad);

对于托管和非托管,字设置需要相同,所以如果dll是32位,那么.NET也必须如此。