C 呼叫DLL時引數問題的一點心得

2021-04-28 12:39:39 字數 1628 閱讀 6269

c#匯入dll時,引數怎麼定義是乙個比較頭痛的問題。特別是指標型別的引數,關於此問題本人有點不成熟的經驗。

以 getcomputername這個函式為例。

函式原型如下:

這個lpbuffer就是下個string型的指標,其實無論是什麼型別的指標,對於windows來說都是乙個32位的無符號的整數,也就是乙個內在位址,函式之所以使用指標就是要向指標所指向的記憶體空間寫入資料。

我們用c#呼叫時也要給它傳遞乙個指標,還要對應一塊分配的空間 。

下面是**:

其實和c++在呼叫的本質是一樣的,都要分配空間並將空間的位址傳給函式。只是c#是執行在託管環境,所以對空間的分配的資料的讀取都要特殊處理。還是更簡單的方法,就是用stringbuilder。本質上還是和上面一樣的,只不過是c#替你做了得多工作。

[dllimport("kernel32.dll")]

static extern bool getcomputername(stringbuilder lpbuffer, ref int lpnsize);

對於結構體也是一樣,以下面結構體為例說明一下。

引數是乙個結構體的指標,函式會填充結構體的各個字段,其實就是向這塊記憶體空間的不同位置寫入不同的資料。

根據結構體的定義有5個dword和乙個128位的char陣列,所以要給這個結構體分配148位空間。結構體的第乙個欄位這是個結構體的大小,我們用 marshal.writeint32(pv, 148);寫入結構體的大小(這也是windows api在使用結構體的乙個特點,就是大部分結構體在傳給函式填充前要指定其大小。),然後執行函式。如果函式正常返回,就可以根據結構體的定義從相應的位置讀出資料。

marshal.readint32(pv, 4);讀取第二個整數也就是majorversion,marshal.readint32(pv, 12);第四個是buildnumber,marshal.ptrtostringansi((intptr)(pv.toint32() + 20));五個整數之後是csdversion。

寫上面的內容只是想分析一下機理,如果學習過彙編就很好理解了。

下面是通常的做法:

使用Authentication的一點心得

我寫了乙個例子程式 第一次使用基於froms的驗證 首先假設使用者登陸成功 這個一般從資料庫得到驗證 然後寫入驗證票據authentication.以後的頁面中判斷這個使用者是否通過驗證,如果沒有,重定向到使用者登陸頁面 如果已經登陸,則執行業務邏輯 本文重點在討論authentication在角色...

python def和lambda的一點心得

原文 python def和python lambda這2個有相似點也有不同點,今天給大家分享下自己的心得吧。先說說2個的相似點 這兩個很重要的相似點就是都可以定義一些固定的方法或者是流程,供給程式來呼叫,比如我們要定義乙個變數加2的方法。首先看python def吧。definfo x retur...

python def和lambda的一點心得

原文 python def和python lambda這2個有相似點也有不同點,今天給大家分享下自己的心得吧。先說說2個的相似點 這兩個很重要的相似點就是都可以定義一些固定的方法或者是流程,供給程式來呼叫,比如我們要定義乙個變數加2的方法。首先看python def吧。definfo x retur...