tlbimp.exe将HWND转换为_RemotableHandle

时间:2010-11-02 11:50:42

标签: .net com interop com-interop

我们的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 ++组件中使用。 我不想在互操作中进行更改,因为它们是在每次构建时自动编译的。

还有其他方法可以解决这个问题吗?

2 个答案:

答案 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程序集内的类型。