我们的COM组件接口有下一个方法:
HRESULT CreatePluginWindow([in] HWND hParent, [in] RECT* prcView);
我们将在.NET应用程序中使用它,但是此接口的interop看起来像这样:
void CreatePluginWindow(ref interop.alfrontx._RemotableHandle hParent, ref interop.alfrontx.tagRECT prcView)
根据我的调查,如果没有不安全的代码,就无法使用此方法。 我不想更改COM接口以便使用除HWND类型之外的hParent,因为它在许多C ++组件中使用。 我不想在互操作中进行更改,因为它们是在每次构建时自动编译的。
还有其他方法可以解决这个问题吗?
答案 0 :(得分:1)
执行此操作不是Tlbimp,当您构建非托管COM服务器时,这是由midl.exe注入的。窗口句柄是互操作障碍,因为它在32位程序中是32位值,在64位程序中是64位值。像所有句柄一样。
看一下Windows SDK include目录中的wtypes.idl文件,你会发现在那里声明了_RemotableHandle。更进一步,您将看到将HWND映射到RemotableHandle的#define:
#ifndef _MIDL_DECLARE_WIREM_HANDLE
DECLARE_WIREM_HANDLE( HWND );
// etc..
#endif
尽可能接近,当您将/ D _MIDL_DECLARE_WIREM_HANDLE传递给midl.exe时,您将获得一个没有RemoteHandle包装器的类型库。不可否认,我真的不明白这是如何运作的。
答案 1 :(得分:1)
我认为您可以使用以下代码将IntPtr转换为_RemotableHandle:
interop.alfrontx._RemotableHandle HWNDtoRemotableHandle(IntPtr handle)
{
return (interop.alfrontx._RemotableHandle)Marshal.PtrToStructure(handle, typeof(interop.alfrontx._RemotableHandle));
}
因此,您可以轻松地使用上述函数从IntPtr获取_RemotableHandle,并且无需更改.NET程序集内的类型。