託管平台呼叫的引數封送

2021-10-06 02:21:18 字數 2916 閱讀 5736

在平台呼叫中,因為託管型別和非託管型別之間有差異,所以需要進行入參與出參的封送才可正常的呼叫非託管的函式。在所有要進行封送的引數型別之中,大體分為兩種:

可直接複製到本機結構中的型別(blittable)和非直接複製到本機結構中的型別(non-bittable)

blittable型別轉換對照表:

windows 資料型別

非託管資料型別

託管資料型別

託管資料型別解釋

byte/uchar/uint8

unsigned char

system.byte

無符號8位整型

sbyte/char/int8

char

system.sbyte

有符號8位整型

short/int16

short

system.int16

有符號16位整型

ushort/word/uint16/wchar

unsigned short

system.uint16

無符號16位整型

bool/hresult/int/long

long/int

system.int32

有符號32位整型

dword/ulong/uint

unsigned long/unsigned int

system.uint32

無符號32位整型

int64/longlong

_int64

system.int64

有符號64位整型

uint64/dwordlong/ulonglong

_uint64

system.uint64

無符號64位整型

int_ptr/handle/wparam

void*/int或_int64

system.intptr

有符號指標型別

handle

void*

system.uintptr

無符號指標型別

float

float

system.single

單精度浮點數

double

double

system.double

雙精度浮點數

除了上表列出來的簡單型別之外,還有一些複製型別也屬於可直接複製到本機結構中的資料型別:

(1) 資料元素都是可直接複製到本機結構中的一元陣列,如整數陣列,浮點陣列等

(2)只包含可直接複製到本機結構中的格式化值型別

(3)成員變數全部都是可複製到本機結構中的型別且作為格式化型別封送的類

上面提到的格式化指的是——在型別定義時,成員的記憶體布局在宣告時就明確指定的型別。在**中用structlayout屬性修飾被指定的型別,並將structlayout的layoutkind屬性設定為sequential或explicit。

non-bittable型別轉換對照表:

windows 資料型別

非託管資料型別

託管資料型別

託管資料型別解釋

bool

bool

system.boolean

布林型別

wchar/tchar

char/ wchar_t

system.char

ansi字元/unicode字元

lpcstr/lpcwstr/lpctstr/lpstr/lpwstr/lptstr

const char*/const wchar_t*/char*/wchar_t*

system.string

ansi字串/unicode字串,如果非託管**不需要更新此字串時,此時用string型別在託管**中宣告字串型別

lpstr/lpwstr/lptstr

char*/wchar_t*

system.stringbuilder

ansi字串/unicode字串,如果非託管**需要更新此字串,然後把更新的字串傳回託管**中,此時用stringbuilder型別在託管**中宣告字串

除了上表列出的型別之外,還有一些型別屬於非可直接複製型別,例如其他指標型別和控制代碼型別等。

相較於可直接複製型別,non-bittable型別因為在託管**記憶體中的儲存形式與非託管**中的記憶體儲存形式不同,所以需要做中間轉換處理,才能複製到被呼叫的函式之中。

若要封送結構體,需要先知道非託管函式的結構體引數的詳細資訊,然後再根據該資訊在託管**之中構建出相對應的結構體進行初始化並封送。在非託管函式宣告時,結構體引數要用ref關鍵字進行修飾,不能使用out,因為out引數在傳入前不會進行初始化。

若要封送類,也是同樣的道理,先要明確非託管函式中引數類的詳細資訊,然後在託管**中構建同樣的類,初始化並且進行封送。需要注意的是,在非託管函式宣告時,類引數要用[in]關鍵字進行修飾,這樣才能使初始值傳入到函式體之中,如果有進行修改並返回的需求,則還要加上[out]關鍵字,寫法[in, out]。

本文參考博主learning hard,如要更為細緻的了解互操作呼叫的相關知識,請參閱該博主的博文

平台呼叫 結構的封送

關於結構的封送,先看乙個類 structlayoutattribute 該類的作用是,允許控制記憶體中類或結構的資料字段的物理布局。該類的層次結構為 system.object system.attributesystem.runtime.interopservices.structlayoutat...

原 C 與非託管 封送和自動封送

之前說到了如何從c函式宣告通過簡單的查詢替換生成乙份c 的靜態引用宣告 c 與非託管 初體驗 因為只是簡單說明,所以全部採用的是基礎型別匹配和自動封送。自動封送雖然能省去我們不少編碼時間,但如果不理解自動封送背後的實際行為,那就如同看魔術師的黑盒子,知其然不知其所以然。而且,自動封送也不是永遠有效的...

託管呼叫非託管的DLL

dllimport createnewprocess.dll charset charset.unicode public static extern bool createprocess marshalas unmanagedtype.lpwstr string fullpath 以上是定義入口,...