我想使用C++和WRL (Windows 运行时 C++ 模板库)创建一个WinRT组件,以便通过 C# 静态方法调用在托管代码中使用。
int sum = Math.FastAdd(5,6);
对我不起作用的实现如下。
这里有什么问题?
- 在IDL文件中创建一个数学类。它将是托管端静态方法的宿主。使用FastAdd方法创建IMathStatics接口。这个只包含一堆静态方法。使用带有IMathStatics参数的静态属性标记Math类。
导入“inspectable.idl”;
#define COMPONENT_VERSION 1.0
命名空间 WRLNativeComponent
{
运行时类数学;
[uuid(EFA9D613-BA8F-4F61-B9E7-C6BE7B7765DD)]
[exclusiveto(WRLNativeComponent.Math)]
[版本(COMPONENT_VERSION)]
接口 IMathStatics : IInspectable
{
HRESULT FastAdd([in] int a, [in] int b, [out, retval] int* value);
}
[uuid(650438BA-C401-49E1-8F06-58DCD5A4B685), 版本(COMPONENT_VERSION)]
接口 IMath : IInspectable
{
HRESULT InstanceMethod(void);
}
[静态(WRLNativeComponent.IMathStatics,COMPONENT_VERSION)]
[版本(COMPONENT_VERSION),可激活(COMPONENT_VERSION)]
运行时类数学
{
[默认] 接口 IMath;
}
}
- 创建MathStatics C++ 类。让InspectableClassStatic宏指向IMathStatics字符串标识符。添加ActivatableStaticOnlyFactory宏以指向MathStatics类实现。
#pragma 一次
#include <wrl.h>
#include "MyMath_h.h" // 从 IDL 生成
使用命名空间 Microsoft::WRL;
命名空间 WRLNativeComponent {
数学类:公共 Microsoft::WRL::RuntimeClass,
ABI::WRLNativeComponent::IMath>
{
InspectableClass(RuntimeClass_WRLNativeComponent_Math, BaseTrust);
上市:
数学(无效){}
〜数学(无效){}
STDMETHODIMP InstanceMethod() 覆盖
{
返回 S_OK;
}
};
类 MathStatics : public Microsoft::WRL::ActivationFactory
{
InspectableClassStatic(InterfaceName_WRLNativeComponent_IMathStatics, BaseTrust);
上市:
数学静态(无效){}
〜数学(无效){}
STDMETHODIMP FastAdd(_In_ int a, _In_ int b, _Out_ int* value) 覆盖
{
if (value == nullptr) 返回 E_POINTER;
*值 = a + b;
返回 S_OK;
}
};
可激活类(数学);
ActivatableStaticOnlyFactory(MathStatics);
}
编译后,将创建WRLNativeComponent.winmd文件。我可以看到具有公共静态 FastAdd方法的Math类。
构造 C# 客户端以调用静态方法。进行调用时,将引发“System.InvalidCastException” 。这有望正常工作。