平台呼叫P INVOKE 一 基礎篇

2021-05-28 08:35:57 字數 1857 閱讀 7430

平台呼叫技術(p/invoke):主要用於處理在託管**中呼叫c/c++庫函式及win32 api函式等非託管函式的情形

一、基本要素

乙個簡單例子:

c++宣告:

extern "c" __declspec(dllexport) int multiply(int factora, int factorb);

實現:int multiply(int factora, int factorb)

託管**(c#)呼叫此非託管宣告:

class invoker

總結: (宣告託管函式)1.函式宣告:

extern修飾符和static修飾符

2.dllimport屬性 (常用)

指定動態庫:指明平台要呼叫的dll名稱,此項不可缺少。

指定入口點:entrypoint 欄位按名稱或序號指定 dll 函式,可以使用與原dll中不同名稱,不填此項,預設為跟原函式名稱一致。

指定字符集:

charset 字段控制字串封送處理並確定平台呼叫在 dll 中查詢函式名的方式。有窄版本 (ansi) 和寬版本 (unicode)。msdn如下說明:

成員名稱

說明ansi

以多位元組字串的形式封送字串。 

auto

針對目標作業系統適當地自動封送字串。在 windows nt、windows 2000、windows xp 和 windows server 2003 系列上預設值為 unicode;在 windows 98 和 windows me 上預設值為 ansi。儘管公共語言執行庫預設值為 auto,使用語言可重寫此預設值。例如,預設情況下,c# 將所有方法和型別都標記為 ansi。 

none

此值已過時,它與 charset.ansi 具有相同的行為。 

unicode

以 unicode 2 位元組字元形式封送字串。 

指定呼叫約定:callingconvention欄位指定呼叫在非託管**中實現的方法所需的呼叫約定。動態鏈結庫匯出的一般有兩種呼叫協議,__stdcall和_cdecl。__cdecl是c/c++和mfc程式預設使用的呼叫約定:採用__cdecl約定時,函式引數按照從右到左的順序入棧,並且由呼叫函式者把引數彈出棧以清理堆疊。因此,實現可變引數的函式只能使用該呼叫約定。__stdcall呼叫約定用於呼叫win32 api函式。採用__stdcal約定時,函式引數按照從右 到左的順序入棧,被呼叫的函式在返回前清理傳送引數的棧,函式引數個數固定。

msdn如下說明:

成員名稱

說明cdecl

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

fastcall

不支援此呼叫約定。 

stdcall

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

thiscall

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

winapi

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

3、注意事項:

數個數、順序、型別必須保持「等價」一致,函式名稱和引數名稱可以不一致。

使用平台呼叫(P Invoke)

使用平台呼叫 p invoke,它的全名叫平台呼叫 platform invoke 用於呼叫dll 中實現的非託管的單調 flat 程式設計介面,被稱為使用c或c 呼叫約定 calling conventions 最有名的例子是win32 程式設計介面,這是乙個巨大的庫,它公開了windows 所有...

C 高階與初心 (二)P Invoke平台呼叫

最近某個專案要採集交易終端的資訊用於監管,主要廠商給出了api,c 版的。開啟hard模式!c 呼叫c 的dll基本就兩種方法 加乙個vc 專案包一層,或者使用p invoke 平台呼叫 前者對於純c 的客戶端來說,增加了複雜性。那就只剩下平台呼叫了。使用平台呼叫的過程比較艱辛,主要遇到了兩個問題 ...

C 如何呼叫C 基礎篇

閒暇之餘,記一下筆記!記錄一下c 如何呼叫c 的動態庫 dll 步驟 addoperate.h extern declspec dllexport int sum int a,int b class addoperate addoperate.cpp include addoperate.h inc...