在.NET与C++之间传输集合数据
上一篇《在C++中反射调用.NET(二)》中,我们尝试了反射调用一个返回DTO对象的.NET方法,今天来看看如何在.NET与C++之间传输集合数据。
使用非泛型集合的委托方法
先看看.NET类中的一个返回列表数据的方法:
//返回List或者数组,不影响 C++调用
public List<IUserInfo> GetUsers(string likeName)
{
List<IUserInfo> users = new List<NetLib.IUserInfo>();
for (int i = 0; i < 10; i++)
{
IUserInfo userinfo = GetUserByID(i);
userinfo.Name += likeName;
users.Add(userinfo);
}
//return users.ToArray();
return users;
}
public IUserInfo GetUserByID(int userId)
{
IUserInfo userinfo= EntityBuilder.CreateEntity<IUserInfo>();
userinfo.ID = userId;
userinfo.Name = "姓名_" + userId;
userinfo.Birthday = new DateTime(1980, 1, 1);
return userinfo;
}
该方法没有什么复杂业务逻辑,就是将传递进来的参数给DTO对象,创建包含10个这样的对象的列表并返回而已。
对于 GetUsers方法,我们可以创建下面的委托方法来绑定:
Func<String, IEnumerable> fun;
注意这里使用的是非泛型的 IEnumerable接口,在C++需要使用下面这个命名空间:
using namespace System::Collections;
那么为何不能使用泛型集合呢?
using namespace System::Collections::Generic;
因为在C++端,没有直接引用用户项目的.NET程序集,并不知道泛型集合类型的具体类型,IUserInfo这个接口无法直接访问,好在IEnumerable<T>也是继承 IEnumerable 的,所以可以当做非泛型对象在C++中访问,因此创建上面的委托方法是可行的。
C++中的列表对象list
下面看看完整的C++/CLI反射调用的代码:
std::list<CppUserInfo> GetUsers(String^ likeName)
{
//调用.NET方法,得到结果
MethodInfo^ method = dotnetObject->GetType()->GetMethod("GetUsers", BindingFlags::Public | BindingFlags::Instance);
Func<String^, IEnumerable^>^ fun = (Func<String^, IEnumerable^>^)Delegate::CreateDelegate(Func<String^, IEnumerable^>::typeid,
this->dotnetObject, method);
IEnumerable^ result = fun(likeName);
std::list<CppUserInfo> cppResult;
for each (Object^ item in result)
{
Func<String^, Object^>^ entityProp = EntityHelper::EntityCallDelegate(item);
CppUserInfo user;
user.ID = (int)entityProp("ID");
user.Name = (String^)entityProp("Name");
user.Birthday = Convert2CppDateTime((DateTime^)entityProp("Birthday"));
cppResult.push_back(user);
}
return cppResult;
}
在C++中,常常使用 list来表示一个列表数据,例如上面方法中的代码:










