积极答复者
C++通过反射调用C#的Dll接口时,接口参数为自定义类对象的数组,应如何设定参数?

问题
-
关于在托管C++程序中通过反射调用C#的Dll的问题,请大侠帮看看,详细如下:
有一个C#的DLL(A.dll)中有如下一个函数:
public bool Test(int count, Detail[] Details)
其中Detail是一个自定义类型,定义如下:
public class Detail
{
public string MsgCode { get; set; }
public string[] MsgParams { get; set; }
}
我现在想要在C++程序中使用上面这个接口函数,这个C++程序是托管程序。
下面是我的代码(简化版),可是运行时有问题,详细见下:
//创建C#类实例
Assembly^ assem = Assembly::LoadFrom(gcnew String("A.dll"));
Type^ type = assem->GetType("libA.XXX");
Object^ obj = Activator::CreateInstance(type);
// 创建自定义类型数组
Type^ type_Details = assem->GetType("libA.Detail");
array<Object^>^ Details = gcnew array<Object^>(5);
for( int i = 0; i < 5; ++i )
{
Details[i] = Activator::CreateInstance(type_Details);
}
MethodInfo^ method = type->GetMethod("Test");
Object^ obj_result;
array<Object^>^args;
args = gcnew array<Object^>(4);
args[ 0 ] = 1;
args[ 1 ] = Details;//这个是输出参数
obj_result = method->Invoke(obj, args); // 错误信息:不能转换类型'System.Object[]'到'libA.Detail[]'
现在的问题是调用的C#函数的参数是自定义类型的数组时就不好使,
如果不是数组,或者是内置类型数组都没有问题。请问应该如何传递参数?
答案
-
真不容易,终于找到个折衷办法,第一次用C++/CLR,不太熟悉,只能这样了。
Type^ type_responseDetails = assem->GetType("libA.Detail");
Array^ arrDetails = Array::CreateInstance(type_responseDetails ,count);
array<Detail^>^ Details = (array<Detail^>^)arrDetails; // 此强制转换成功
你可以尝试使用 arrDetails 来作为参数与C# DLL 交互。
- 已编辑 Skyseer 2012年12月13日 9:03
- 已标记为答案 holmesning 2012年12月13日 10:58
全部回复
-
上面代码是C#的,c++中模仿着做了一个。
typeof(array<>);这句编译有错误,在c++中改为array<Object^>::typeid
但在new Type{type_Details}时会有错误,提示我抽象的类型转换失败。
我又尝试了其他方法动态创建,CreateInstance+MakeArrayType来动态创建对象,代码如下
Type^ type_responseDetails = assem->GetType("libA.Detail");
Object^ Details =Activator::CreateInstance(type_responseDetails->MakeArrayType(count));
运行时遇到新的错误:"No parameterless constructor defined for this object."
但C#程序中libA.Detail已经有无参数的构造函数。为什么还有错误提示呢?挺困惑。
-
真不容易,终于找到个折衷办法,第一次用C++/CLR,不太熟悉,只能这样了。
Type^ type_responseDetails = assem->GetType("libA.Detail");
Array^ arrDetails = Array::CreateInstance(type_responseDetails ,count);
array<Detail^>^ Details = (array<Detail^>^)arrDetails; // 此强制转换成功
你可以尝试使用 arrDetails 来作为参数与C# DLL 交互。
- 已编辑 Skyseer 2012年12月13日 9:03
- 已标记为答案 holmesning 2012年12月13日 10:58