關於c 中的dllimport

2021-04-13 22:34:55 字數 3081 閱讀 2211

msdn中對dllimportattribute的解釋是這樣的:可將該屬性應用於方法。dllimportattribute 屬性提供對從非託管 dll 匯出的函式進行呼叫所必需的資訊。作為最低要求,必須提供包含入口點的 dll 的名稱。

並給了乙個示例:

[dllimport("kernel32.dll", entrypoint="movefilew",  setlasterror=true,

charset=charset.unicode, exactspelling=true,

callingconvention=callingconvention.stdcall)]

public static extern bool movefile(string src, string dst);

上網搜了一下,最常見的就是使用它來呼叫win32的api,例如上面所示。或者呼叫一下c或c++編寫的dll。

這東西沒怎麼用過。只是前幾天忽然分配下乙個臨時的任務,做乙個「停車廠管理」的小東西,聽說是乙個大幹部的小孩子要弄這麼個東西,那幹部是公司的客戶,討論正經事之餘又拜託了我們做這麼個小東西。其中用到了微控制器模擬車輛出入的一些訊號。

我對微控制器一竅不通,好在有人寫好了輪詢微控制器的dll,我只管呼叫,由於是c++寫的,於是將dll拷貝到bin目錄後(這dllimport會從程式啟動目錄開始查詢相應名稱的dll,未找到則轉至system32下查詢),用dllimport來呼叫,但在這個過程中遇到了幾個問題:

1.看了一下c++的**,需要用到的只有三個方法:

bool openserialport1()

bool fngetio(unsigned char& p1, unsigned char& p2, unsigned char& p3)

bool closeserialport1()

於是就在自己的程式中寫了:

using system.runtime.interopservices;

[dllimport("getiodll.dll", entrypoint = "openserialport1")]

public static extern bool openserialport1();

[dllimport("getiodll.dll", entrypoint = "fngetio")]

public static extern bool fngetio(ref byte p1, ref byte p2, ref byte p3);

[dllimport("getiodll.dll", entrypoint = "closeserialport1")]

public static extern bool closeserialport1();

然而程式在執行時無論如何總是提示「找不到入口點」,搞得懵了,只好上網搜去,最後下了乙個叫exescope的小軟體,裝完之後檢視該dll,果然如貼子中寫的,dll中的函式名稱發生了變化,分別成了:

?openserialport1@@ya_nxz

?fngetio@@ya_naae00@z

?closeserialport1@@ya_nxz

將這些怪怪的名稱代入到entrypoin中,編譯執行,沒有問題了。

2.可是接上微控制器之後,問題又來了,雖然openserialport1返回的結果是true,但fngetio讀出一資料全是0,按理應該是全1才對。來了乙個同事,說反正有原始碼,把原來的dll弄成標準c的試試,標準c不標準c的我也沒明白,讓那人給改了一下,把編譯之後的dll拷到自己程式的bin下,將entrypoin換成正常的函式名,執行,這回是真的ok了。

讀寫.ini檔案時,也會用到dllimport,不過現在.ini檔案好像用得少了,下面是讀寫的程式:

publicstring path;

[dllimport("kernel32")]

privatestaticexternlong writeprivateprofilestring(string section,string key,string val,string filepath);

[dllimport("kernel32")]

privatestaticexternint getprivateprofilestring(string section,string key,string def,stringbuilder

retval,int size,string filepath);

public inifile(string inipath)

path = inipath;

publicvoid iniwritevalue(string section,string key,string value)

writeprivateprofilestring(section,key,value,this.path);

publicstring inireadvalue(string section,string key)

stringbuilder temp = new stringbuilder(255);

int i = getprivateprofilestring(section,key,"",temp,255,this.path);

return temp.tostring();

網上關於dllimport的很多問題是由於所調方法的引數比較複雜,現在我還沒用到,看到一篇貼子,引數中帶指標的,也先錄下來,以備將來查用:

引數是用指標來獲取乙個陣列:int getdata(byte * pbuffer)  

pbuffer是陣列的首位址,也就是說getdata會寫pbuffer[0],pbuffer[1]....pbuffer[100];

答曰:[dllimport("yourdllfile.dll"]  

private static extern int getvalue([marshalas(unmanagedtype.lparray)]byte pvalue);

如果是out引數,可以如下  

[dllimport("yourdllfile.dll")]  

private static extern int getvalue([out,marshalas(unmanagedtype.lparray)]byte pvalue); 

關於C 中的DLLImport

並給了乙個示例 dllimport kernel32.dll entrypoint movefilew setlasterror true,charset charset.unicode,exactspelling true,callingconvention callingconvention.s...

關於C 中的DLLImport

關於 c 中的 dllimport msdn 中對dllimportattribute 的解釋是這樣的 可將該屬性應用於方法。dllimportattribute 屬性提供對從非託管 dll 匯出的函式進行呼叫所必需的資訊。作為最低要求,必須提供包含入口點的 dll 的名稱。dllimport us...

關於C 中的DLLImport (引)

msdn中對dllimportattribute的解釋是這樣的 可將該屬性應用於方法。dllimportattribute 屬性提供對從非託管 dll 匯出的函式進行呼叫所必需的資訊。作為最低要求,必須提供包含入口點的 dll 的名稱。並給了乙個示例 dllimport kernel32.dll e...