C 總結(四)呼叫C 動態庫

2021-09-22 03:49:29 字數 2196 閱讀 4202

由於公司很多底層的sdk,都是c++開發,上層的應用軟體卻是c# winform程式。在實際工作的過程中,就經常碰到了c# 程式呼叫c++ 動態庫的問題。最近一直在和c++ 打交道,c# 怎麼呼叫c++ 類庫函式。也遇到了一些問題,所以就來總結總結c#程式呼叫c++動態庫時的各種坑。

1. 可能遇到的問題:

c#在呼叫動態庫的過程中我也遇到了以下一些問題:

1、c++中有指標,c#中需要使用指標嗎?

由於c++中的動態庫中有指標引數,因此我也是用.net的不安全**,使用了c#的指標,但是也還是出現了一些問題,如在c#中傳入的引數是乙個二維陣列時就出現了問題,最後只能改c++函式傳入引數的引數型別。

2、c#和c++中的型別如何轉換呢?

雖然c#和c++比較類似,但是其給我們的引數型別我們要與c#的引數型別一一對應起來,具體看後續說明。

3、c++函式中的callingconventioncharset 怎麼設定?

呼叫c++函式之前一定要先確認,否則可能出現函式呼叫導致堆疊不對稱。原因可能是託管的 pinvoke 簽名與非託管的目標簽名不匹配的問題。函式的callingconvention和charset,可以檢視動態庫對應的 .h標頭檔案。

4、如何反編譯c++的dll的名稱,埠?

可以通過dependency walker工具進行反編譯檢視別人寫的動態庫的資訊

5、指標函式如何傳參?

對於函式需要的指標函式,c# 呼叫時,可以定義委託來傳入引數。 

6、需要注意c++ dll 編譯的平台是x86還是x64,是多位元組的還是雙位元組的(unicode)。

2. 通過dependency walke檢視dll的名稱,埠

3. 如何呼叫

c#呼叫c++動態庫一般我們這樣寫

[dllimport(sdk, charset = charset.ansi, callingconvention =callingconvention.stdcall)]

public

static

extern

int iksdk_release();

1. dllimport的第乙個引數sdk是動態庫dll的路徑,此dll放在程式執行的根目錄或者c:windows/sytem32下,建議在程式根目錄建立乙個子目錄來放置相應的c++ 動態庫檔案,方便以後更新。
2. callingconvention 引數是c#呼叫c++的方式 是個列舉 msdn解釋如下:

cdecl

呼叫方清理堆疊。這使您能夠呼叫具有varargs的函式(如printf),使之可用於接受可變數目的引數的方法。 

fastcal

不支援此呼叫約定。

stdcall

被呼叫方清理堆疊。這是使用平台 invoke 呼叫非託管函式的預設約定。 

thiscall

第乙個引數是this指標,它儲存在暫存器 ecx 中。其他引數被推送到堆疊上。此呼叫約定用於對從非託管 dll 匯出的類呼叫方法。 

winapi

此成員實際上不是呼叫約定,而是使用了預設平台呼叫約定。例如,在 windows 上預設為 stdcall,在 windows ce.net 上預設為 cdecl。 

3. charset引數是控制名稱重整以及將字串引數封送到函式中的方式。 預設值為 charset.ansi。

4. entrypoint引數

用於標識函式在 dll 中的位置。在託管物件中,目標函式的原名或序號入口點將標識跨越互動操作邊界的函式。此外,您可以將入口點對映到乙個不同的名稱,這實際上是將函式重新命名。一般預設不設定此引數。

5. 其他引數,請檢視msdn對於 dllimportattribute 的說明。

4. 其他說明

c# 呼叫c++ 動態庫,還有乙個特別麻煩的問題就是引數對於的問題。後續會結合網上的資料總結乙份詳細的對照表。

出處:

C呼叫C 動態庫,靜態庫

c呼叫c 動態庫,靜態庫 1 include 2 using namespace std 34 class paul 5 10 11 int paul add int a,int b 12 17 18 extern c 如果沒有則不行 19 25 1 include 2 extern void ca...

VC 呼叫C 動態庫

近期專案中,需要訪問客戶資料庫,客戶不希望直接訪問其資料庫,而是以動態庫介面的形式開放,還是用c 開發的。經過不斷嘗試,總結方法如下 包含動態庫 using test.dll using namespace test lib using namespace runtime interopservic...

C呼叫動態庫,windows linux

i.windows平台下c呼叫動態庫的方法 case 1 如果提供了.lib和.dll,則不需要動態載入,因為動態庫的.lib中含有dll的所有匯出符號 參考 俞甲子等.程式設計師的自我修養 1 假設動態庫的原始檔math.c包含乙個add函式,被宣告為匯出函式 可被庫外部呼叫 extern c d...