日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

在C++中反射调用.NET(二)

發(fā)布時間:2023/12/15 c/c++ 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在C++中反射调用.NET(二) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

反射調(diào)用返回復(fù)雜對象的.NET方法

定義數(shù)據(jù)接口

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

先看看.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; }} }

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

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

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

EntityBuilder對象是PDF.NET SOD框架中的一個實體構(gòu)造器,調(diào)用CreateEntity方法可以根據(jù)一個接口創(chuàng)建一個動態(tài)實體類對象,通過這種方式,我們可以不用去關(guān)心實體類的構(gòu)造細節(jié),僅僅關(guān)心方法調(diào)用的數(shù)據(jù)接口。在后面的示例中,我們都會通過這種接口對象的方式來傳遞數(shù)據(jù)。

?

綁定委托方法

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

Func<int, Object> fun;

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

CppUserInfo GetUserByID(int userId){//調(diào)用.NET方法,得到結(jié)果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);//轉(zhuǎn)換托管類型數(shù)據(jù)到本機結(jié)構(gòu)體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;}

在上面的代碼中,通過委托方法調(diào)用:

Object^ result = fun(userId);

?

使用SOD DTO 對象

我們得到了.NET程序集的方法返回的DTO對象,但是如何取出它的數(shù)據(jù)賦值給我們的C++本機代碼呢?
所以這里涉及到2個問題:
1,從Object對象取出數(shù)據(jù);
2,將數(shù)據(jù)轉(zhuǎn)換并且賦值給C++本地數(shù)據(jù)結(jié)構(gòu)

對于第一個問題,我們可以反射DTO對象的屬性,然后跟本地數(shù)據(jù)接口一一對應(yīng),但是,本來我們已經(jīng)在反射調(diào)用方法了,再來一次反射事情就復(fù)雜了。
幸好,我們的DTO接口對象它是一個動態(tài)創(chuàng)建的SOD實體類對象,由于SOD實體類有類似“字典”的功能,可以通過相關(guān)方法進行訪問。

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

public object PropertyList(string propertyFieldName)

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

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對象轉(zhuǎn)換到C++結(jié)構(gòu)體

在示例中,我們定義了一個CppUserInfo結(jié)構(gòu)體:

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

托管字符串與本機字符串

這個結(jié)構(gòu)體跟C#版本的接口 IUserInfo對應(yīng),但是結(jié)構(gòu)體成員有幾個需要注意的地方:

CString Name;

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

#include <atlstr.h>

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

#include <cstringt.h>?

?

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

// //要使用下面的方法,請先 #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* 類型的指針,在方法結(jié)尾必須釋放此指針占用的內(nèi)存,所以這種形式的轉(zhuǎn)換還是比較麻煩。
有關(guān)托管字符串跟C++本機字符串的轉(zhuǎn)換,可以參考下面2篇文章:

http://bbs.csdn.net/topics/280024331

http://blog.csdn.net/windren06/article/details/7839985

托管日期與本機日期數(shù)據(jù)

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

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++的相互轉(zhuǎn)換,基本上就能夠使用.NET的DTO對象了,因為其它數(shù)字類型只要類型兼容,是可以直接使用的,比如int類型。

轉(zhuǎn)換到本機結(jié)構(gòu)體

下面再回來看看 GetUserByID 方法內(nèi)的對象數(shù)據(jù)轉(zhuǎn)換部分:

//轉(zhuǎn)換托管類型數(shù)據(jù)到本機結(jié)構(gòu)體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"));

現(xiàn)在再看看,采用類似“字典”訪問方式的SOD DTO對象,給C++本地結(jié)構(gòu)體轉(zhuǎn)換賦值數(shù)據(jù),就很方便了,這也是本篇選擇SOD框架作為C++與.NET通信的原因了。

為何不使用序列化的問題

在進行分布式跨平臺調(diào)用的時候,序列化常常作為一個有效手段被大量使用,但是我們的應(yīng)用有幾個特點:
1,沒有分布式,在進程內(nèi)進行不同語言平臺調(diào)用;
2,不知道反序列化的類型,因為C++沒有直接引用任何.NET框架自身之外的.NET程序集;
3,序列化需要使用反射,而我們本來已經(jīng)在反射了,會加重負擔;

除此之外,使用序列化還會有額外的工作:
4,使用序列化會要求被調(diào)用端進行額外的封裝;
5,雙方需要制定通用的通信協(xié)議,并且定制序列化過程,比如常見RPC框架約定的序列化協(xié)議

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

?

下一篇,我們將介紹C++與.NET如何傳遞集合對象的問題。
(未完待續(xù))

?

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的在C++中反射调用.NET(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 午夜欧美精品久久久久久久 | 黄色片亚洲 | 欧美成综合 | 伊人网中文字幕 | 亚洲精品欧美激情 | 日韩一级黄色大片 | 国产在线免费av | caoporn超碰97 | 精品国产一区二区三区在线观看 | 国语精品久久 | 亚洲精品国产精品乱码桃花 | 国产日韩精品一区二区三区在线 | 麻豆精品一区二区三区 | 天堂视频一区二区 | 嫩草网站入口 | 91成人在线观看喷潮蘑菇 | 91视频久久久久 | 另类激情 | 中文无码av一区二区三区 | 国产黄页| 国产精品第三页 | 亚洲在线影院 | 大黑人交交护士xxxxhd | 免费色网 | 91成人天堂久久成人 | 72pao成人国产永久免费视频 | 超碰在线最新 | 欧美综合第一页 | 久久一级黄色片 | 日本老熟妇乱 | 男人天堂一区 | 日韩乱码人妻无码中文字幕 | 亚洲第一狼人区 | 久久深夜 | 国产四区 | 黑人极品ⅴideos精品欧美棵 | 色翁荡息又大又硬又粗又爽 | 国产精品手机在线 | 国语对白 | 国产成人精品免费看视频 | 成年人在线免费观看视频网站 | 亚洲无打码 | 欧美日韩高清 | 在线播放中文字幕 | avtt在线| 一级黄色aa | 精品久久久久久中文字幕 | av无码久久久久久不卡网站 | 伊人影院中文字幕 | 99久久久无码国产精品免费蜜柚 | www.猫咪av.com| 91成人免费视频 | 成人免费在线观看网站 | 久久这里有精品视频 | 超碰在线国产97 | 五月激情小说 | 成人在线观看免费高清 | 天天躁日日躁狠狠躁免费麻豆 | 在线观看一二区 | aⅴ在线免费观看 | 国产不卡视频一区二区三区 | 女性向小h片资源在线观看 日本天天操 | 国产a一区二区三区 | 成人爱爱网站 | 中文字幕亚洲色图 | av片久久 | 欧美福利片在线观看 | 成人国产精品免费观看 | 亚洲影院中文字幕 | 成年人看的黄色 | 欧美日韩字幕 | 啦啦啦视频在线观看 | 国产页 | 日本免费在线视频观看 | 免费精品无码AV片在线观看黄 | 欧美日韩在线视频观看 | 国产成人精品视频在线 | 狠狠网| 欧洲美女与动交zozzo | 特级淫片裸体免费看冫 | 久久精品亚洲精品国产欧美 | a天堂av| 亚洲国产精品一区二区尤物区 | 国产毛片久久久久 | 欧美黑人疯狂性受xxxxx喷水 | 熊猫av | 最新中文字幕在线视频 | 久久久国产精品x99av | 一级黄网 | 国产无遮挡免费 | 超碰伊人网 | 欧美少妇一级片 | a在线天堂 | 亚洲欧美强伦一区二区 | 婷婷丁香六月 | 亚洲欧美视频在线播放 | 国产一区午夜 | 伊人久久91 | 美女av免费|