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...