Re: [問題] C#引用C++的dll用DLLIMPORT失敗 需轉換?

看板C_and_CPP作者 (lightyen)時間5年前 (2018/08/08 11:15), 編輯推噓5(504)
留言9則, 6人參與, 5年前最新討論串2/2 (看更多)
※ 引述《Stevenashh (YO!!!)》之銘言: : 開發平台(Platform): WIN 7 : 編譯器: visual studio 2017 : 額外使用到的函數庫(Library Used): 外部dll : 問題(Question): : 平時是寫C#,但近期需要使用C#呼叫其他廠商c++的dll(不曉得是manage還unmanage) : 查詢利用DLLIMPORT可以呼叫 但失敗了(應該不是使用錯誤) : 出現的錯誤如圖 https://imgur.com/a/Hw9DX6G : 原文:https://goo.gl/if1WsW : Google到的原因是沒有c++沒有實作clr(=Unmaged?) : 但我看所有DLLIMPORT的教學都是說C#可以直接呼叫Unmanaged : 抱歉因為不太懂c++ : 跪求大大解惑是什麼原因,或是可以提供我關鍵字讓我繼續往下找 : 我應該做些什麼動作才能將這包dll轉換成C#可以IMPORT的版本 : 補充說明(Supplement): : 願以1000P微薄小心意回饋 首先要確認的是要引用的 dll 是 managed 或是 unmanaged。 - managed 指的是給CLR托管 有記憶體垃圾回收C#,VB,C++/CLI 屬於這類。 - unmanaged 非托管的代碼則是要自己得要處理記憶體問題, 傳統的windows api或者COM介面或者是其他人寫的native C++都是這種形式的。 (稱native只是為了和C++/CLI有所區隔,可以想成是又快又猛又易翻車的C++) 依你要的需求,大概是使用C#來呼叫unmanaged code相去不遠了。 這種用C#和原生C++摻在一塊做牛丸的混合編程, 其中最直接相關庫的就是 System.Runtime.InteropServices 這東西搞起來非常的麻煩,不僅要知道native c++的api形式, 還要熟悉C++與C#的用法規則,不然很容易出錯也不好debug。 ## 在此我先弄一個範例: https://github.com/lightyen/WpfMessageBox 其中建立了一個WPF專案,設計一個按鈕, 在點選了按鈕之後會去呼叫user32.dll中的MessageBox來顯示一個對話框。 如果你有一些工具軟體去查看user32.dll,(例如DLL Export Viewer) 你會發現user32.dll存在兩個與MessageBox有關的Function, 一個是A結尾一個是W結尾,A指的是ASCII,W指的是寬字元。 不過我們已經把CharSet設成Auto了,.NET平台會自動地去選擇合適的。 (比較重要的點是在C#中,string全部是寬字元的,要和unmanaged code互通時要多留意) ## 好了,現在我們可以來實作牛丸了 首先新增一個*.cs 然宣告一個static class來當我們的介面參考, 然後再宣告一個static extern方法來描述MessageBox這個函式, 把函式名稱、參數形式、返回值依照API文件規範依樣畫葫蘆。 IntPtr在C++中代表的就是指標,而IntPtr.Zero則代表NULL, HWND是一個視窗的handle,也是一個整數。 (其實指標在記憶體中也不過是一個整數罷了。) (user32.dll不需要填絕對路徑,因為windows已經內定註冊了, 第三方的library應該還是要填詳細的路徑。) LPCTSTR =>'一個tchar的唯讀字串',在這裡用一個string代表。 使用了這個方法後,平台會隱隱地偷偷地把string的內容先放到unmanaged空間, 然後再做參數傳給MessageBox。 假若今天要傳的是一個物件(void*), 則我們必須先從unmanaged要一塊記憶體空間,然後填上相應資料, 在透過IntPtr寫入(或讀出),最後用完後還要記得回收記憶體, 整個過程真的蝦雞巴麻煩的。 參考:System.Runtime.InteropServices.Marshal AllocHGlobal,FreeHGlobal,SizeOf ## 最後設計的部分 許多c++的函式都用一個整數代表功能的體現, 在C#中我們可以來為這些功能(flag)寫成一個enum,加些註解, 或者把一些資料包裝成一個class,再加上一些額外的功能, 使得在調用這些unmanaged code能更加舒服一些。 ## 更多的範例 https://github.com/lightyen/COMInterop ## 更多的關鍵字 pinvoke, Interop, DllImport, Marshal, IntPtr, UnmanagedType, StructLayout, MarshalAs -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 210.66.174.153 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1533698113.A.344.html

08/08 13:40, 5年前 , 1F
給個推~
08/08 13:40, 1F

08/08 17:04, 5年前 , 2F
推,Unicode/ASCII function 確實常常製造問題要分清楚
08/08 17:04, 2F

08/08 22:08, 5年前 , 3F
受益良多 推推
08/08 22:08, 3F

08/09 09:49, 5年前 , 4F
先推再看
08/09 09:49, 4F

08/12 05:54, 5年前 , 5F
對岸有一本 ISBN 是 9787115204349 的書不錯看。
08/12 05:54, 5F

08/12 05:55, 5年前 , 6F
雖說絕版但還買得到,只是書有附光碟不能走正常管道出境
08/12 05:55, 6F

08/17 08:18, 5年前 , 7F
其實說麻煩就Marshal那段特別討厭而已,很多c#其實都
08/17 08:18, 7F

08/17 08:19, 5年前 , 8F
是刻UI然後把state全部給dll管的話 其實難度不高
08/17 08:19, 8F

08/17 08:19, 5年前 , 9F
dll要expose任何結構出來的是地獄麻煩鬼...
08/17 08:19, 9F
文章代碼(AID): #1RQc11D4 (C_and_CPP)
文章代碼(AID): #1RQc11D4 (C_and_CPP)