使用PInvoke互操作,讓C Sharp 和C++愉快的交互優勢互補

2020-12-22 一線碼農的vlog

一:背景

1. 講故事

如果你常翻看FCL的源碼,你會發現這裡面有不少方法藉助了C/C++的力量讓C#更快更強悍,如下所示:

聯想到上一篇阿里簡訊netsdk也是全用C++實現,然後用C#做一層殼,兩者相互打輔助彰顯更強大的威力,還有很多做物聯網的朋友對這種.Net互操作技術太熟悉不過了,很多硬體,視頻設備驅動都是用C/C++實現,然後用winform/WPF去做管理界面,C++還是在大學裡學過,好多年沒接觸了,為了練手這一篇用P/Invoke來將兩者相互打通。

二:PInvoke互操作技術

1. 一些前置基礎

這裡我用vs2019創建C++的Console App,修改兩個配置: 將程序導出為dll,修改成compile方式為 Compile as C++ Code (/TP)。

2. 基本類型的互操作

簡單類型是最好處理的,基本上int,long,double都是一一對應的,這裡我用C++實現了簡單的Sum操作,畫一個簡圖就是下面這樣:

新建一個cpp文件和一個h頭文件,如下代碼。

有一個注意的地方就是 extern "C",一定要用C方式導出,如果按照C++方式,Sum名稱會被編譯器自動修改,不信你把 extern "C" 去掉,我用ida打開給你看一下,被修改成了 ?Sum@@YAHHH@Z , 尷尬。

接下來把C++項目生成好的 ConsoleApplication1.dll copy到C#的bin目錄下,代碼如下:

2. 字符串的互操作

我們知道託管代碼和非託管代碼是兩個世界,這中間涉及到了兩個世界的的類型映射,那映射關係去哪找呢? 微軟的msdn還真有一篇介紹 封送通用類型對照表: https://docs.microsoft.com/zh-cn/dotnet/standard/native-interop/type-marshaling ,大家有興趣可以看一下。

從圖中可以看到,C#中的string對應C++中的char*,所以這裡就好處理了。

然後我們看一下C#這邊怎麼寫,通常string在C++中使用asc碼,而C#中是Unicode,所以在DllImport中加一個CharSet指定即可。

3. 複雜類型的處理

複雜類型配置對應關係就難搞了,還容易搞錯,錯了弄不好還內存洩漏,怕了吧,幸好微軟提供了一個小工具 P/Invoke Interop Assistant ,它可以幫助我們自動匹配對應關係,我就演示一個封送Person類的例子。

從圖中可以看到,左邊寫好 C++,右邊自動給你配好 C# 的映射類型,非常方便。

可以看到C++中AddPerson返回了char*,在C#中我們用IntPtr來接,然後用Marshal將指針轉換string,接下來用工具生成好的C#代碼拷到項目中來,如下:

4. 回調函數(異步)的處理

前面介紹的3種情況都是單向的,即C#向C++傳遞數據,有的時候也需要C++主動調用C#的函數,我們知道C#是用回調函數,也就是委託包裝,具體我就不說了,很開心的是C++可以直接接你的委託,看下怎麼實現。

從代碼中看到,PCALLBACK就是我定義了函數指針,接受int參數。

這裡我做了一個自定義的delegate,因為我使用 Action<T>不接受泛型拋異常(┬_┬)。

四:總結

這讓我想起來前段時間用python實現的線性回歸,為了簡便我使用了http和C#交互,這次準備用C++改寫然後PInvoke直接交互就利索了,好了,藉助C++的生態,讓 C# 如虎添翼吧~~~

相關焦點

  • 資源共享 優勢互補 互惠互贏 科學發展 ——上海市第六人民醫院與...
    資源共享 優勢互補 互惠互贏 科學發展 ——上海市第六人民醫院與福建省人民政府共建國家創傷區域醫療… 2020-09-23 11:24 來源:澎湃新聞·澎湃號·政務
  • 「物聯網」Rust系列3:Rust如何避免C和c++的陷阱
    第一部分:「物聯網」Rust系列1:用Rust重寫了物聯網平臺並成功  第二部分:「物聯網」Rust系列(2):以火取光,C和C++的問題  所以現在我已經徹底,也許不公平烤幾個設計缺陷的一種程式語言超過四十歲,經營著世界上大多數嵌入式設備,讓我們來談談如何鏽設計出這些問題,同時仍然保留了C和c++的部分,讓他們強大的和有用的語言。
  • C++的轉換手段並與explicit關鍵詞配合使用
    如子類和父類之間的多態類型轉換。reinterpret_cast,僅僅重新解釋類型,但沒有進行二進位的轉換。static_cast:任何具有明確定義的類型轉化,只要不包含底層const,都可以使用static_cast,舉一個例子。
  • 使用open-webkit-sharp打開報表頁面,實現js腳本對C 代碼的調用
    書接上回由於使用的帆軟設計器的版本較低,所以在對圖表設置了圖標縮放功能後,IE瀏覽器並不支持,所以為了兼容處理,替換為使用webkit的谷歌內核打開帆軟報表。下載open-webkit-sharp資源,然後將Cores文件夾和References文件夾下的所有文件拷貝到項目所在路徑下,然後把Binary文件夾析的文件全部拷貝到項目所在路徑下(如果使用的是Framework2.0的框架則複製Binary NET2下面的文件)。當然小編已經把需要的資源整理好,不需要再自己進行拷貝替換了,需要的可以找小編索取哦。
  • OriginOS給用戶帶來「獨特」交互方式
    而讓廣大用戶更加驚訝的是OriginOS帶來的創新性交互方式,其與桌面風格一樣都可以進行自定義設置,讓用戶可以打造出獨一無二的交互界面,非常吸引人!交互池帶來全新交互方式OriginOS帶來的交互池功能非常新穎,該功能能夠對手機屏幕側邊的手勢操控進行自定義設置,用戶只需要點擊交互池圖標就可以調整交互方式,非常簡單。
  • 哈蘇X1D II 50c 體驗:操作和手機一樣簡單,但畫質仍然標杆
    按鍵更少的話,操作就更容易上手。即便你之前沒有用過哈蘇系列的相機,簡單幾個按鍵和直觀的觸控 UI 也不難使用。而且 X1D II 50c 的觸控界面也跟手機很相似,如果讓我來比喻,我認為這是相機中的傻瓜式操控。它除了有直觀說明功能的圖標,UI 也能進行自定設置。用戶能像操控手機桌面那樣,長按拖動圖標就能夠移動它的位置,方便自己操作。
  • card是卡片,sharp是尖銳的,那card sharp是什麼意思?
    我們知道card的意思是「卡片」,sharp的意思是「尖銳的」,那card sharp是什麼意思呢?card sharp的意思是「a person who earns money by playing cards dishonestly」,即「(玩紙牌時)作弊贏錢的人,耍老千的人」。
  • 郴州市邊坡噴播機滄州質量的使用和基本操作
    郴州市邊坡噴播機滄州質量的使用和基本操作   郴州市邊坡噴播機滄州質量的使用和基本操作    同時攪拌液體、半流體,並可各類肥料、滅蟲、殺菌、除疫的噴施用設備。如果此時混合軸已經到位,而節流閥是合適的,那麼:液壓油會變質,取代液壓油。
  • C Sharp 數據操作系列 - 1. SQL基礎操作
    0.前言前篇介紹了一些資料庫的基本概念和以及一些常見的資料庫,讓我們對資料庫有了一個初步的認識。這一篇我們將繼續為C#數據操作的基礎填上一個空白-SQL語句。SQL(Structured Query Language,結構化查詢語言)是一種特定的程式語言,用於管理資料庫系統,操作數據甚至編寫一些程序。
  • 還不懂c++vector的用法,你憑什麼勇氣來的!
    今天給大家帶來一篇c++vector的介紹,難以置信這篇文章寫了我三天,不過總算整理完畢,現在分享給大家。模板類vector 和 array是數組的替代品。模板類vector 類似於string類,也是一種動態數組。 在 c++ 中,vector 是一個十分有用的容器。
  • C/C++編程筆記:C數組、字符串常量和指針!三分鐘弄懂它
    想弄懂C語言中數組和指針的關係嗎?這篇文章就佔據你三分鐘時間,看完你肯定會有收穫! int列表[MAX_SIZE + 1]; C數組開始於元素0,所以像陣列定義 int a[3];將創建三個int元件,可尋址如a[0],a[1],和a[2] 請注意,即使定義很難說a[3],也沒有名為a[3] 與其他變量一樣,全局和靜態數組元素默認情況下初始化為
  • 4K花園與咪咕公司達成戰略合作 將在4K等領域實現資源優勢互補
    來源:TechWeb.com.cn【TechWeb】9月4日消息,日前,四開花園網絡科技(廣州)有限公司(以下簡稱「4K花園」)與咪咕文化科技有限公司(以下簡稱「咪咕公司」)達成戰略合作,雙方將在4K、8K超高清視頻及VR內容領域實現資源優勢互補
  • 重構交互邏輯 OriginOS如何讓操作更便捷?
    這款系統與其它手機系統的一大不同之處在於,其對於智慧型手機的交互邏輯進行了大幅度簡化,將原來需要多次點擊才能夠實現的功能簡化為只需一步操作,甚至是無需操作即可實現,下面便來一起看看OriginOS是如何做到的。
  • 優勢互補 實現共贏
    項目建成後將進一步提升廈門城市旅遊國際形象,與廈門現有旅遊資源形成自然和人文的互補、日遊和夜遊的互補、童趣遊和景觀遊的互補,優化廈門旅遊業態。 陳家東向付書全一行介紹了廈門市經濟社會發展、招商引資和馬鑾灣新城片區建設運營情況。
  • 為什麼手機使用安卓typeC接口?它與micro-usb比優勢在哪兒?
    現在越來越多的手機使用type c的接口,比較熟悉的就有小米魅族OPPO vivo華為三星等,那麼我們今天就討論一下它的c接口,它好在哪裡?他和Micro USB, 有什麼優勢。所以市面上在type c普及以後才會出現閃充手機,因為比起傳統的手機,理論上type c能夠支持100w的閃充(當然如今oppo打破了這個常規已經將快充做到125w)那麼,除了傳送速度和供電強度外以外,Micro USB和type c相比,還有哪些優勢
  • 特性完成:VS2019 v16.8全面支持C++協程
    提供一個嚴格遵循C++標準的協程實現,使得用戶可以編寫和使用可移植代碼。2. 確保那些使用實驗版本協程的用戶可以毫不費力地升級到v16.8而無需改動他們的代碼。隨著提案的更改,我們會儘可能增加新的支持,而不破壞針使用早期協程版本的代碼。這當然不是標準的:它仍然接受所有舊的關鍵字,名稱和籤名,和上面的第一個目標對應。
  • 搭建C語言開發環境,其實只需要兩個工具就行了!
    在手打代碼之前,我們當然要先搭建自己的開發環境,對於c語言的學習來說,其實只需要兩個工具就行了,那就是文本編輯器和c編譯器了。文本編輯器顧名思義就是你編輯代碼文本的工具,其實和電腦裡自帶記事本一樣,能輸入各種數字、符號、字母,理論上來說,記事本就是一個文本編輯器,只不過因為無法直接對txt文件進行編譯。
  • C語言與C++、C Sharp究竟是什麼關係?(附福利)
    C語言和C++的關係:C++既是面向過程又是面向對象,而且它還繼承了C語言的所有優點,並且對C語言功能做了很多擴充,可以認為C++就是C語言的增強版。3. C#是完全面向對象的語言,簡單易學,開發效率非常高。關於這三種語言的關係就介紹這麼多,想要閱讀這3本書籍的小夥伴,可以點擊技術學派頭像-右上角-私信我發送「C語言電子書」即可。分享 IT 技術和行業經驗,請關注-技術學派。
  • 捷宇科技完成國產作業系統及CPU平臺互認證
    捷宇科技作為人工智慧、物聯網技術應用的解決方案提供商,始終倡導融合能力、融合應用、融合服務,與合作夥伴優勢互補,共同完善人工智慧、物聯網產業生態。    目前,捷宇科技基於自主智慧財產權推出的全系列產品,包括智能交互終端、信息交互終端、高拍儀、視頻展臺、成冊掃描儀、攝像頭等產品,已順利完成與中標麒麟、龍芯中科、兆芯、中科方德、萬裡紅和統信UOS等國產作業系統及國產CPU