用非托管接口包装托管接口

Wrapping managed with unmanaged interface

本文关键字:接口 包装      更新时间:2023-10-16

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

我想为这个库提供一个托管包装器。用托管接口包装非托管接口很容易。但是在我的情况下,我希望支持各种接口的用户实现,这意味着我需要在将接口发送到库的非托管部分的深处之前,使用接口的非托管实现并使用它的非托管对口来包装它。

我试过这样做:

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

但是,编译器正确地声明,在非托管类中不能有托管成员。

我可以在这里做一些优雅的事情吗?

当一个库是非托管的,而一个托管语言使用这些库时,这里有一些相关的信息。

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

使用Google c++测试框架

Visual c++用户的重要注意事项而main()函数在不同的库中或在.exe文件时,这些测试将不会运行。原因是Visual中的一个bugc++。当您定义测试时,Google Test会创建某些静态测试对象来注册它们。这些对象不被引用但是它们的构造函数仍然应该运行。当visualc++链接器发现库中没有任何内容被引用在其他地方,它把图书馆扔出去了。你必须参考你的包含主程序中的测试的库,以防止链接器从丢弃它。下面是如何做到这一点。在库代码的某个地方声明函数:

__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。否则您的测试将无法正确运行或根本无法运行。一般这里的结论是:让你的生活更轻松——不要用库!

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

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