C++ 将ref类对象(Uri^)作为本机指针参数传递(IUriRuntimeClass*)
我的代码中有以下midl方法:C++ 将ref类对象(Uri^)作为本机指针参数传递(IUriRuntimeClass*),c++,uwp,c++-cx,midl,C++,Uwp,C++ Cx,Midl,我的代码中有以下midl方法: 接口IMyClass:IInspectable { HESREST函数([in ] Windows .Buffo.URI*URI); } 它生成以下接口方法: IMyClass:公共IIinspectable { 公共:虚拟HRESULT STDMETHODCALLTYPE Func1( /*[in]*/_RPC__in_opt ABI::Windows::Foundation::IUriRuntimeClass*uri)=0; } 该接口在应用程序端实现,其对
接口IMyClass:IInspectable
{
HESREST函数([in ] Windows .Buffo.URI*URI);
}
它生成以下接口方法:
IMyClass:公共IIinspectable
{
公共:虚拟HRESULT STDMETHODCALLTYPE Func1(
/*[in]*/_RPC__in_opt ABI::Windows::Foundation::IUriRuntimeClass*uri)=0;
}
该接口在应用程序端实现,其对象被传递到我的代码中,我只能“看到”该接口。我想知道调用
Func1
并将Windows::Foundation::Uri
对象作为参数传递的最佳方法是什么
由于C2664错误,仅传递ref类对象不起作用Windows::Foundation::Uri^u=ref新Uri(…);
IMyClassObj->Func1(u);//错误无法将参数1从Windows::Foundation::Uri^'转换为“ABI::Windows::Foundation::IUriRuntimeClass”*
我可以通过reintrepret_铸造来实现我的目标:Windows::Foundation::Uri^u=ref新Uri(…);
ABI::Windows::Foundation::IUriRuntimeClass*uu=reinterpret\u cast(u);
MyClassObj->Func1(u);//这个很好用
在这种情况下,重新解释是正确的方法吗?或者有没有其他方法可以将Uri^对象作为IUriRuntimeClass*参数传递?一种稍微干净一点的方法是尽快将其封装在
ComPtr
中,以便在抛出任何异常时获得正确的行为等(您的方法今天可能很简单,但以后可能会变得更复杂)
大概是这样的:
#include <wrl/client.h>
#include <windows.foundation.h>
// Dummy method that just prints out the URI to the debug console
HRESULT MyFunc(ABI::Windows::Foundation::IUriRuntimeClass* uri)
{
HSTRING str{};
HRESULT ret{ S_OK };
if (SUCCEEDED(ret = uri->get_AbsoluteUri(&str)))
OutputDebugString(WindowsGetStringRawBuffer(str, nullptr));
WindowsDeleteString(str);
return ret;
}
void Test()
{
using namespace Microsoft::WRL;
// Create the ref class
auto uri = ref new Windows::Foundation::Uri(L"http://www.bing.com");
// Wrap in a dummy IUnknown wrapper. In theory you could use
// IInspectable or even IUriRuntimeClass but if you're going to
// copy-paste the code elsewhere, IUnknown is the "safest" thing you
// can reinterpret_cast<>() to.
ComPtr<IUnknown> iUnknown{ reinterpret_cast<IUnknown*>(uri) };
// Try to cast it to the IUriRuntimeClass, and call our method if
// it succeeds
ComPtr<ABI::Windows::Foundation::IUriRuntimeClass> iUri{};
if (SUCCEEDED(iUnknown.As(&iUri)))
MyFunc(iUri.Get());
}
#包括
#包括
//只将URI打印到调试控制台的伪方法
HRESULT MyFunc(ABI::Windows::Foundation::IUriRuntimeClass*uri)
{
HSTRING str{};
HRESULT ret{S_OK};
if(成功(ret=uri->get_AbsoluteUri(&str)))
OutputDebugString(WindowsGetStringRawBuffer(str,nullptr));
WindowsDeleteString(str);
返回ret;
}
无效测试()
{
使用名称空间Microsoft::WRL;
//创建ref类
自动uri=ref新窗口::基础::uri(L)http://www.bing.com");
//用一个虚拟的IUnknown包装器包装。理论上你可以使用
//IInspectable甚至IUriRuntimeClass但是如果你想
//把代码复制粘贴到别处,IUnknown是你最“安全”的东西
//可以将_cast()重新解释为。
ComPtr iUnknown{reinterpret_cast(uri)};
//尝试将其强制转换为IUriRuntimeClass,并在以下情况下调用我们的方法
//它成功了
ComPtr iUri{};
if(成功(iUnknown.As(&iUri)))
MyFunc(iUri.Get());
}
一种稍微简洁的方法是尽快将其包装在ComPtr
中,以便在抛出任何异常时获得正确的行为等(您的方法今天可能很简单,但以后可能会变得更复杂)
大概是这样的:
#include <wrl/client.h>
#include <windows.foundation.h>
// Dummy method that just prints out the URI to the debug console
HRESULT MyFunc(ABI::Windows::Foundation::IUriRuntimeClass* uri)
{
HSTRING str{};
HRESULT ret{ S_OK };
if (SUCCEEDED(ret = uri->get_AbsoluteUri(&str)))
OutputDebugString(WindowsGetStringRawBuffer(str, nullptr));
WindowsDeleteString(str);
return ret;
}
void Test()
{
using namespace Microsoft::WRL;
// Create the ref class
auto uri = ref new Windows::Foundation::Uri(L"http://www.bing.com");
// Wrap in a dummy IUnknown wrapper. In theory you could use
// IInspectable or even IUriRuntimeClass but if you're going to
// copy-paste the code elsewhere, IUnknown is the "safest" thing you
// can reinterpret_cast<>() to.
ComPtr<IUnknown> iUnknown{ reinterpret_cast<IUnknown*>(uri) };
// Try to cast it to the IUriRuntimeClass, and call our method if
// it succeeds
ComPtr<ABI::Windows::Foundation::IUriRuntimeClass> iUri{};
if (SUCCEEDED(iUnknown.As(&iUri)))
MyFunc(iUri.Get());
}
#包括
#包括
//只将URI打印到调试控制台的伪方法
HRESULT MyFunc(ABI::Windows::Foundation::IUriRuntimeClass*uri)
{
HSTRING str{};
HRESULT ret{S_OK};
if(成功(ret=uri->get_AbsoluteUri(&str)))
OutputDebugString(WindowsGetStringRawBuffer(str,nullptr));
WindowsDeleteString(str);
返回ret;
}
无效测试()
{
使用名称空间Microsoft::WRL;
//创建ref类
自动uri=ref新窗口::基础::uri(L)http://www.bing.com");
//用一个虚拟的IUnknown包装器包装。理论上你可以使用
//IInspectable甚至IUriRuntimeClass但是如果你想
//把代码复制粘贴到别处,IUnknown是你最“安全”的东西
//可以将_cast()重新解释为。
ComPtr iUnknown{reinterpret_cast(uri)};
//尝试将其强制转换为IUriRuntimeClass,并在以下情况下调用我们的方法
//它成功了
ComPtr iUri{};
if(成功(iUnknown.As(&iUri)))
MyFunc(iUri.Get());
}
您是直接调用C++类还是正在调用WiMD元数据?MIDL和方法调用在同一个模块的组件中。所以这个电话是直拨电话。虽然接口实现是通过应用程序端的winmd完成的,其对象被传递回“组件”。您应该能够使用ComPtr
并从ref
类获取接口。在模块中,如果你只通过本地C++类型,通常是比较容易的。如果我的理解正确,我希望使用<代码> RealTytCase将<代码> URI^ 对象转换成<代码> COMPTR < /代码>。那么,在转换为<代码> COMPTR < /C>和使用本地指针时,在我的问题正文中有什么不同?您是直接调用C++类还是直接调用WiMD元数据?MIDL和方法调用在同一个模块的组件中。所以这个电话是直拨电话。虽然接口实现是通过应用程序端的winmd完成的,其对象被传递回“组件”。您应该能够使用ComPtr
并从ref
类获取接口。在模块中,如果你只通过本地C++类型,通常是比较容易的。如果我的理解正确,我希望使用<代码> RealTytCase将<代码> URI^ 对象转换成<代码> COMPTR < /代码>。那么,转换成ComPtr与使用本机指针(如我在问题正文中给出的示例)之间有什么区别呢?