我正在尝试为原生 C++ 插件标准编写托管互操作库。这个本机 C++ 库使用与 COM 兼容的接口设计。但是,它不会做任何类注册的事情。与 COM 一样,所有接口都派生自 IUnknown(称为 FUnknown,但无论如何都是相同的 3 个方法)。
我编写了一个简单的 C++ 控制台应用程序,它加载我的托管测试插件并通过导出的方法检索初始(根)接口(对象工厂模式 - 很像 com)。我使用第 3 方 DllExport 代码属性实现 - 这似乎工作正常。C++ 测试应用使用 LoadLibrary/GetProcAddress 并成功检索对接口的引用。我可以在我的托管导出函数中设置一个断点,它会按预期命中。
然后 C++ 测试应用程序在 IUnknown(部分)接口上调用 AddRef 并返回 2 - 正如预期的那样。请注意,我的托管接口定义(对应部分)不是从 IUnknown 派生的 - 或包含这些方法。我想说这意味着托管编组魔法已经介入并提供了CCW。
然后 C++ 测试应用程序在工厂接口上调用一个简单的方法 - 一个只返回一个 int32 的方法 - 并且也到达托管实现(断点被命中),但是当该方法返回时,它会抛出一个 AccessViolationException - 在托管的某处 -无管理的过渡。
class IPluginFactory : public FUnknown
{
public:
// removed other methods before and after this one
virtual int32 PLUGIN_API countClasses () = 0;
};
int32 是一个#define 并且 PLUGIN_API 被定义为 __stdcall - 据我所知,它与 COM 兼容。
我定义的该接口的托管表示如下:
[ComImport]
[Guid("same guid as in C++ file")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPluginFactory
{
[return: MarshalAs(UnmanagedType.I4)]
Int32 CountClasses();
}
此方法的托管实现仅返回一个硬编码数字 (1)。
我已经尝试了很多事情(太多了,我什至都记不清了),目前不知道如何解决这个问题,或者问题可能是什么。
任何帮助深表感谢。谢谢!
编辑:请求有关 FUnknown 的详细信息:
class FUnknown
{
public:
virtual tresult PLUGIN_API queryInterface (const TUID iid, void** obj) = 0;
virtual uint32 PLUGIN_API addRef () = 0;
virtual uint32 PLUGIN_API release () = 0;
};