亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

在C++中反射調用.NET的方法(二)

2020-01-26 14:15:42
字體:
來源:轉載
供稿:網友

反射調用返回復雜對象的.NET方法

定義數據接口

上一篇在C++中反射調用.NET(一)中,我們簡單的介紹了如何使用C++/CLI并且初步使用了反射調用.NET程序集的簡單方法,今天我們看看如何在C++與.NET程序集之間傳遞復雜對象。

先看看.NET程序集的一個返回對象的方法:

 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; }

其中 IUserInfo是一個用戶信息接口:

using System;namespace NetLib{ public interface IUserInfo { DateTime Birthday { get; set; } int ID { get; set; } string Name { get; set; } }}

接口內容很簡單,有int,string,DateTime三種類型的屬性,所以可以把它當做.NET與C++傳遞數據的DTO對象接口。

在方法 GetUserByID 中,有一行代碼:

IUserInfo userinfo= EntityBuilder.CreateEntity<IUserInfo>();

EntityBuilder對象是PDF.NET SOD框架中的一個實體構造器,調用CreateEntity方法可以根據一個接口創建一個動態實體類對象,通過這種方式,我們可以不用去關心實體類的構造細節,僅僅關心方法調用的數據接口。在后面的示例中,我們都會通過這種接口對象的方式來傳遞數據。

綁定委托方法

下面我們來看看如何在C++/CLI中反射調用GetUserByID 這個方法。

雖然方法返回的是IUserInfo,但是對于我們的C++程序端來說,它并不知道IUserInfo這個接口對象,因為此接口沒有在C++程序端定義,C++程序也沒用引用它所在的.NET程序集,所以我們在反射調用GetUserByID 方法的時候,只能使用“弱類型”的Object,幸運的是我們調用的是返回值,而不是參數(反過來就不行,后面會有介紹),創建下面的委托對象是合法的:

Func<int, Object> fun;

詳細的C++/CLI反射代碼如下:

CppUserInfo GetUserByID(int userId) {  //調用.NET方法,得到結果  MethodInfo^ method = dotnetObject->GetType()->GetMethod("GetUserByID", BindingFlags::Public | BindingFlags::Instance);  Func<int, Object^>^ fun = (Func<int, Object^>^)Delegate::CreateDelegate(Func<int, Object^>::typeid, this->dotnetObject, method);  Object^ result = fun(userId);  //轉換托管類型數據到本機結構體  Func<String^, Object^>^ entityProp =EntityHelper::EntityCallDelegate(result);  CppUserInfo user;  user.ID = (int)entityProp("ID");  user.Name = (String^)entityProp("Name");// MarshalString((String^)entityProp("Name"));  user.Birthday = Convert2CppDateTime((DateTime^)entityProp("Birthday"));  return user; }

在上面的代碼中,通過委托方法調用:

Object^ result = fun(userId); 

使用SOD DTO 對象

我們得到了.NET程序集的方法返回的DTO對象,但是如何取出它的數據賦值給我們的C++本機代碼呢?

所以這里涉及到2個問題:

1,從Object對象取出數據;

2,將數據轉換并且賦值給C++本地數據結構

對于第一個問題,我們可以反射DTO對象的屬性,然后跟本地數據接口一一對應,但是,本來我們已經在反射調用方法了,再來一次反射事情就復雜了。

幸好,我們的DTO接口對象它是一個動態創建的SOD實體類對象,由于SOD實體類有類似“字典”的功能,可以通過相關方法進行訪問。

實體類基類的一個方法定義:

public object PropertyList(string propertyFieldName)

我們反射此方法并且綁定一個委托對象來調用它:

 static Func<String^, Object^>^ EntityCallDelegate(Object^ entity) {  //實體類基類的一個方法定義:  //public object PropertyList(string propertyFieldName)  Type^ base = entity->GetType()->BaseType;  MethodInfo^ methodEntity = base->GetMethod("PropertyList", BindingFlags::Public | BindingFlags::Instance);  Func<String^, Object^>^ funEntity = (Func<String^, Object^>^)Delegate::CreateDelegate(Func<String^, Object^>::typeid,       entity, methodEntity);  //示例 String^ result = (String^)funEntity("Name");  return funEntity; }

然后,就能像下面這樣使用了:

Func<String^, Object^>^ entityProp =EntityHelper::EntityCallDelegate(result);int id = (int)entityProp("ID");

將.NET對象轉換到C++結構體

在示例中,我們定義了一個CppUserInfo結構體:

struct CppUserInfo{ int ID; //wstring Name; CString Name; tm Birthday;};

托管字符串與本機字符串

這個結構體跟C#版本的接口 IUserInfo對應,但是結構體成員有幾個需要注意的地方:

CString Name;

字符串類型的“名字”成員,要在C++中使用字符串類型,必須在C++文件中包含下面的頭文件:
如果不是 MFC應用程序,包含下面這個:

#include <atlstr.h>

否則,需要包含這個頭文件:

#include <cstringt.h>  

如果不是使用CString,而是 wstring,那么需要定義一個方法來實現托管字符串到本機字符串的轉換: 

//  //要使用下面的方法,請先 #include <string>  // static wstring MarshalString(String ^ s) {  wstring os;  const wchar_t* chars =   (const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();  os = chars;  Marshal::FreeHGlobal(IntPtr((void*)chars));  return os; }

上面的方法申明了一個 wchar_t* 類型的指針,在方法結尾必須釋放此指針占用的內存,所以這種形式的轉換還是比較麻煩。
有關托管字符串跟C++本機字符串的轉換。

托管日期與本機日期數據

在C++中表示日期的結構體是 tm,但是需要注意的是 tm的year部分僅能夠表示與1900的差值,所以我們可以寫下面2個方法來簡單的轉換:

 static tm Convert2CppDateTime(DateTime^ dt) {  tm result;  result.tm_year = dt->Year - 1900;  result.tm_mon = dt->Month;  result.tm_wday = dt->Day;  return result; } static DateTime^ Covert2NetDateTime(tm cppDate) {  return gcnew DateTime(   cppDate.tm_year + 1900,    cppDate.tm_mon,    cppDate.tm_wday  ); }

有了字符串跟日期類型的.NET與C++的相互轉換,基本上就能夠使用.NET的DTO對象了,因為其它數字類型只要類型兼容,是可以直接使用的,比如int類型。

轉換到本機結構體

下面再回來看看 GetUserByID 方法內的對象數據轉換部分:

//轉換托管類型數據到本機結構體   Func<String^, Object^>^ entityProp =EntityHelper::EntityCallDelegate(result);   CppUserInfo user;   user.ID = (int)entityProp("ID");   user.Name = (String^)entityProp("Name");// MarshalString((String^)entityProp("Name"));   user.Birthday = Convert2CppDateTime((DateTime^)entityProp("Birthday"));

現在再看看,采用類似“字典”訪問方式的SOD DTO對象,給C++本地結構體轉換賦值數據,就很方便了,這也是本篇選擇SOD框架作為C++與.NET通信的原因了。

為何不使用序列化的問題

在進行分布式跨平臺調用的時候,序列化常常作為一個有效手段被大量使用,但是我們的應用有幾個特點:

1,沒有分布式,在進程內進行不同語言平臺調用;

2,不知道反序列化的類型,因為C++沒有直接引用任何.NET框架自身之外的.NET程序集;

3,序列化需要使用反射,而我們本來已經在反射了,會加重負擔;

除此之外,使用序列化還會有額外的工作:

4,使用序列化會要求被調用端進行額外的封裝;

5,雙方需要制定通用的通信協議,并且定制序列化過程,比如常見RPC框架約定的序列化協議

所以,經過仔細考慮后,放棄了使用序列化方式來進行C++與.NET進行進程內通信的想法。

以上所述是小編給大家介紹的在C++中反射調用.NET的方法(二),希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久资源免费视频| 中文字幕久久久av一区| 日韩精品久久久久久福利| 久久久久久91| 欧美超级乱淫片喷水| 亚洲激情视频在线观看| 国产亚洲精品久久久久久| 国产精品丝袜白浆摸在线| 国产欧美精品久久久| 日本伊人精品一区二区三区介绍| 狠狠躁夜夜躁人人爽天天天天97| 日韩欧美综合在线视频| 国产成人精品一区| 国产又爽又黄的激情精品视频| 亚洲国产第一页| 亚洲国产精品一区二区三区| 国产精品va在线播放我和闺蜜| 欧美激情精品久久久久久蜜臀| 亚洲精品国产精品国产自| 国产精品电影久久久久电影网| 这里只有视频精品| 亚洲欧美日韩综合| 国产亚洲成精品久久| 久久久久久久久久久久久久久久久久av| 2019中文字幕在线免费观看| 日韩视频在线观看免费| 中文字幕成人在线| 中文字幕欧美日韩| 中文字幕亚洲激情| 国产精品久久久久久搜索| 欧美一区视频在线| 久操成人在线视频| 自拍偷拍亚洲一区| www日韩欧美| 久久99精品久久久久久噜噜| 欧美高跟鞋交xxxxxhd| 色偷偷偷亚洲综合网另类| 国产欧美精品在线播放| 日韩国产在线播放| 日韩中文字幕国产精品| 日韩高清电影好看的电视剧电影| 国产精品久久久久久久电影| 日韩av最新在线观看| 日韩日本欧美亚洲| 久久99精品国产99久久6尤物| 欧美成人午夜视频| 日韩欧美国产中文字幕| 欧美激情视频一区二区三区不卡| 亚洲欧美成人一区二区在线电影| 亚洲精品国产精品国产自| 亚洲成人激情图| 久久国产精品电影| 亚洲精品久久久久久久久久久| 亚洲国产精品电影在线观看| 欧美性猛交xxx| 2019中文字幕全在线观看| 中文字幕日韩精品在线| 精品偷拍一区二区三区在线看| 精品久久久香蕉免费精品视频| 久久久精品在线| 日日骚久久av| 日韩精品中文字幕在线播放| 欧美日韩激情视频| 国产精品自产拍高潮在线观看| 成人免费午夜电影| 国色天香2019中文字幕在线观看| 亚洲欧美日韩成人| 欧美激情综合色综合啪啪五月| 欧美丰满少妇xxxxx| 国产+人+亚洲| 成人午夜激情免费视频| 日本sm极度另类视频| 久久久久久久久中文字幕| 亚洲欧美中文日韩在线v日本| 亚洲开心激情网| 亚洲国产欧美一区二区三区久久| 欧美大秀在线观看| 日韩电影中文字幕av| 国产精品入口免费视频一| 亚洲美女av在线播放| 亚洲视频国产视频| 久久精品国产亚洲精品| 国产色婷婷国产综合在线理论片a| 亚洲精品av在线播放| 中文字幕亚洲国产| 亚洲天堂av在线播放| 69**夜色精品国产69乱| 亚洲国产精品yw在线观看| 国内精品久久久久影院优| 日韩电影免费在线观看| 在线观看亚洲区| 国产精品入口免费视频一| 国产成人高清激情视频在线观看| 91爱爱小视频k| 福利视频第一区| 午夜精品三级视频福利| 欧美一级视频免费在线观看| 国产精品午夜视频| 中文字幕精品—区二区| 亚洲天堂免费观看| 久久亚洲精品一区| 久久精品国产96久久久香蕉| 欧美精品久久一区二区| 亚洲精品99久久久久中文字幕| 欧美激情视频在线观看| 少妇激情综合网| 久久99亚洲精品| 久久艳片www.17c.com| 亚洲女同精品视频| 成人激情视频小说免费下载| 国产乱肥老妇国产一区二| 91高清视频免费观看| 亚洲欧洲一区二区三区久久| 成人国内精品久久久久一区| 91亚洲一区精品| 亚洲a∨日韩av高清在线观看| 欧美性猛交xxxx黑人猛交| 亚洲精品资源在线| 亚洲最大激情中文字幕| 亚洲开心激情网| 亚洲区bt下载| 欧美xxxx做受欧美.88| 国产精品美女免费| 久久精品视频导航| 日韩欧美国产骚| 在线亚洲欧美视频| 国产精品免费视频久久久| 欧美男插女视频| 亚洲成人久久一区| 欧美国产日韩中文字幕在线| 欧美精品一区二区免费| 久久福利网址导航| 韩国欧美亚洲国产| 国产欧美精品一区二区三区介绍| 日韩一区二区三区在线播放| 97超碰蝌蚪网人人做人人爽| 尤物yw午夜国产精品视频明星| 亚洲国产中文字幕在线观看| 成人精品视频99在线观看免费| 久久国产精品偷| 国产色视频一区| 欧美黑人一级爽快片淫片高清| 精品视频在线播放免| 国模视频一区二区三区| 欧美成人精品一区二区三区| 国产精品一区二区三区久久久| 亚洲毛茸茸少妇高潮呻吟| 日韩专区在线播放| 欧美另类老肥妇| 91精品久久久久久久久青青| 日韩av网站大全| 91精品在线一区| 欧美成人午夜激情在线| 欧美激情精品久久久久久免费印度| 精品久久久久久久久中文字幕| 4438全国亚洲精品在线观看视频| 亚洲综合最新在线| 亚洲视频在线免费看| 久久天天躁狠狠躁夜夜爽蜜月| 最好看的2019年中文视频| 亚洲丁香久久久| 日韩成人免费视频| 法国裸体一区二区| 亚洲视频电影图片偷拍一区|