【问题标题】:tlbimp.exe converts HWND to _RemotableHandletlbimp.exe 将 HWND 转换为 _RemotableHandle
【发布时间】:2011-05-03 21:39:30
【问题描述】:

我们的COM组件接口有下一个方法:

HRESULT CreatePluginWindow([in] HWND hParent, [in] RECT* prcView);

我们将在 .NET 应用程序中使用它,但这个接口的互操作看起来像这样:

void CreatePluginWindow(ref interop.alfrontx._RemotableHandle hParent, ref interop.alfrontx.tagRECT prcView)

根据我的调查,如果没有不安全的代码,就无法使用此方法。 我不想更改 COM 接口以便为 hParent 使用 HWND 类型以外的类型,因为它在许多 C++ 组件中使用。 我不想在互操作中进行更改,因为它们会在每次构建时自动编译。

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

【问题讨论】:

    标签: .net com interop com-interop


    【解决方案1】:

    执行此操作的不是 Tlbimp,这是在您构建非托管 COM 服务器时由 midl.exe 注入的。窗口句柄是互操作障碍,因为它是 32 位程序中的 32 位值和 64 位程序中的 64 位值。像所有手柄一样。

    查看 Windows SDK 包含目录中的 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 包装器的类型库。诚然,我真的不明白这应该如何工作。

    【讨论】:

    • 感谢您的解决方案!添加标志后,我在 wtypes.idl 和 objidl.idl 中出现编译错误(它们使用 HWND 和 HICON)。但我已经在 idl 的开头声明了它们,并希望互操作包含 IntPtr 而不是 _RemotableHandle。
    • @Emendz 你能更详细地了解你是如何解决编译错误的吗?会有很大帮助
    【解决方案2】:

    我认为您可以使用以下代码将 IntPtr 转换为 _RemotableHandle:

        interop.alfrontx._RemotableHandle HWNDtoRemotableHandle(IntPtr handle)
        {
            return (interop.alfrontx._RemotableHandle)Marshal.PtrToStructure(handle, typeof(interop.alfrontx._RemotableHandle));
        }
    

    因此,您可以轻松使用上述函数从 IntPtr 获取 _RemotableHandle,而无需更改 .NET 程序集内的类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-29
      • 2023-01-03
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      相关资源
      最近更新 更多