【发布时间】:2011-04-08 09:29:08
【问题描述】:
我需要在运行时使用反射来制作 COM IntetrOp。我的本机 COM 对象的公开方法有一些参数作为指针 (DWORD*) 和一些双指针 (DWORD**),还有一些是用户定义的类型(例如 SomeUDTType objSmeUDTType),反之亦然它的指针(即 SomeUDTType *pSomeUDTType)。
现在对于动态方法调用,我们有一个选项可以将参数作为对象数组传递,即 object[] 并静态填充该数组。
但我需要传递指针和引用以及指向指针的指针。现在我如何能够将对象数组填充为简单数据类型、指针或引用以及指向指针的指针的混合数据。
工作示例:
本机 COM 公开方法:
STDMETHODIMP MyCallableMethod(DWORD *value_1,BSTR *bstrName,WESContext **a_wesContext)
由 tlbimp.exe (COMInterop) 翻译
UDTINIDLLib.IRuntimeCalling.MyCallableMethod(ref uint, ref string, System.IntPtr)
现在在运行时使用反射在运行时调用这些方法,
看这里:
Assembly asembly = Assembly.LoadFrom("E:\\UDTInIDL\\Debug\\UDTINIDLLib.dll");
Type[] types = asembly.GetTypes();
Type type = null;
//foreach (Type oType in types)
{
try
{
type = asembly.GetType("UDTINIDLLib.RuntimeCallingClass");
}
catch (TypeLoadException e)
{
Console.WriteLine(e.Message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
object parameters = new object[3];
Type CustomType = asembly.GetType("UDTINIDLLib.WESContext");
object oCustomType = Activator.CreateInstance(CustomType);
FieldInfo fieldInfo = CustomType.GetField("MachineName", BindingFlags.Public | BindingFlags.Instance);
string MachineName = "ss01-cpu-102";
string MachineIp = "127.0.0.1";
string Certificate = "UK/78T";
fieldInfo.SetValue(oCustomType, MachineName);
fieldInfo.SetValue(oCustomType, MachineIp);
fieldInfo.SetValue(oCustomType, Certificate);
object obj = Activator.CreateInstance(type);
MethodInfo mInfo = type.GetMethod("MyCallableMethod");
int lengthOfParams = mInfo.GetParameters().Length;
ParameterInfo [] oParamInfos = mInfo.GetParameters();
object[] a_params = new object[lengthOfParams];
int ValueType = 0;
for(int iCount = 0; iCount<lengthOfParams; iCount++)
{
a_params[iCount] = ???; //Now here this array should be populated with corresponding pointers and other objects (i.e WESContext's obj)
}
mInfo.Invoke(obj, a_params);
希望代码能够澄清......如果有任何混淆,请告诉我,我会相应地编辑我的问题。
我被困在这里,如果你能帮助我,我将不胜感激。(我对“动态”关键字感到困惑,希望它能解决问题)
是否需要生成 C++/CLI 包装器?如果在什么情况下? 问候 乌斯曼
【问题讨论】:
-
我严重怀疑你能否完成这项工作。此 COM 服务器似乎没有使用与自动化兼容的参数类型。这些指针实际上看起来像数组。首先让它与互操作库一起工作。如果这不起作用,那么您将不得不为它编写一个 C++/CLI 包装器。
-
这些只是简单的指针。指向 BSTRS 和一些 DWORD 的指针。 BSTR 指针仅指向 BSTR,而 DWORDS 有一些 DWORDS 地址。问题不在这里,无论它们是数组还是简单的指针,问题是在将数据映射到相应的 BSTR 指针和 DWORD 指针的同时使用 InterOp 对方法进行相应的调用,因为在正常情况下它的调用是预期的。我正在使用 Interop 库。此处使用 tlbimp.exe 将其转换为托管 .NET 对象,然后对其应用反射。这是 RCW(运行时可调用包装器),它将调用转移到本机 COM 世界。
-
这是一个很好的问题:您是否尝试过在 没有 反射的情况下调用您的 COM API(即通过在代码中对
MyCallableMethod的简单调用)?它奏效了吗?如果没有,您应该首先专注于完成这项工作,然后将反射留到以后。 -
它在普通调用中工作正常.....对于 ref 没问题..我声明了普通的 uint 并作为 ref 传递它可以工作..
标签: c++ reflection dynamic .net-4.0 com-interop