【问题标题】:How to get access to the native IDataObject如何访问本机 IDataObject
【发布时间】:2012-10-22 03:00:45
【问题描述】:

我正在尝试将 System::Windows::Forms::IDataObject 转换为 ObjIdl.h 中定义的原生 IDataObject。不幸的是,以下源代码不返回本机 IDataObject。

IntPtr pData = System::Runtime::InteropServices::Marshal::GetIUnknownForObject(e->Data);
::IDataObject* data = (::IDataObject*) pData.ToPointer();

如何在拖放期间在 Windows 窗体应用程序中获取本机 IDataObject?

【问题讨论】:

  • 您确定需要它吗?为什么不能使用托管的 IDataObject?尽管您可以通过将对象固定在内存中并重新解释转换来做到这一点,但我怀疑您应该这样做。
  • 是的,我确定我需要它,因为我仅将 Windows 窗体应用程序用于测试目的。在实际项目中,我不会包含托管代码。你能提供一个固定的例子吗?
  • 嗯,有两种可能。如果本机实现和托管实现碰巧共享相同的内存布局,则可以进行强制转换(但不要忘记固定,否则您的对象可能随时被 .NET 框架重新定位!);否则,你需要实现一个原生的adapter
  • Here 是 C# 中固定的示例

标签: c++ .net visual-c++ com c++-cli


【解决方案1】:

使用 C 风格的转换来转换 COM 接口指针是不合法的。您必须使用 QueryInterface() 方法很好地询问。像这样:

 System::Windows::Forms::IDataObject^ obj = Clipboard::GetDataObject();
 ::IUnknown* punk = (::IUnknown*)System::Runtime::InteropServices::Marshal::GetIUnknownForObject(obj).ToPointer();
 ::IDataObject* pdata = nullptr;
 HRESULT hr = punk->QueryInterface(__uuidof(::IDataObject), (void**)&pdata);
 if (SUCCEEDED(hr)) {
     // etc..
 }

【讨论】:

    猜你喜欢
    • 2020-09-09
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 2018-08-08
    相关资源
    最近更新 更多