msdn中對(duì)dllimportattribute的解釋是這樣的:可將該屬性應(yīng)用于方法。dllimportattribute 屬性提供對(duì)從非托管 dll 導(dǎo)出的函數(shù)進(jìn)行調(diào)用所必需的信息。作為最低要求,必須提供包含入口點(diǎn)的 dll 的名稱。
并給了一個(gè)示例:
[dllimport("kernel32.dll", entrypoint="movefilew", setlasterror=true,
charset=charset.unicode, exactspelling=true,
callingconvention=callingconvention.stdcall)]
public static extern bool movefile(string src, string dst);
上網(wǎng)搜了一下,最常見的就是使用它來調(diào)用win32的api,例如上面所示。或者調(diào)用一下c或c++編寫的dll。
這東西沒怎么用過。只是前幾天忽然分配下一個(gè)臨時(shí)的任務(wù),做一個(gè)“停車廠管理”的小東西,聽說是一個(gè)大干部的小孩子要弄這么個(gè)東西,那干部是公司的客戶,討論正經(jīng)事之余又拜托了我們做這么個(gè)小東西。其中用到了單片機(jī)模擬車輛出入的一些信號(hào)。
我對(duì)單片機(jī)一竅不通,好在有人寫好了輪詢單片機(jī)的dll,我只管調(diào)用,由于是c++寫的,于是將dll拷貝到bin目錄后(這dllimport會(huì)從程序啟動(dòng)目錄開始查找相應(yīng)名稱的dll,未找到則轉(zhuǎn)至system32下查找),用dllimport來調(diào)用,但在這個(gè)過程中遇到了幾個(gè)問題:
1.看了一下c++的代碼,需要用到的只有三個(gè)方法:
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();
然而程序在運(yùn)行時(shí)無論如何總是提示“找不到入口點(diǎn)”,搞得懵了,只好上網(wǎng)搜去,最后下了一個(gè)叫exescope的小軟件,裝完之后查看該dll,果然如貼子中寫的,dll中的函數(shù)名稱發(fā)生了變化,分別成了:
[email protected]@ya_nxz
[email protected]@[email protected]
[email protected]@ya_nxz
將這些怪怪的名稱代入到entrypoin中,編譯運(yùn)行,沒有問題了。
2.可是接上單片機(jī)之后,問題又來了,雖然openserialport1返回的結(jié)果是true,但fngetio讀出一數(shù)據(jù)全是0,按理應(yīng)該是全1才對(duì)。來了一個(gè)同事,說反正有源碼,把原來的dll弄成標(biāo)準(zhǔn)c的試試,標(biāo)準(zhǔn)c不標(biāo)準(zhǔn)c的我也沒明白,讓那人給改了一下,把編譯之后的dll拷到自己程序的bin下,將entrypoin換成正常的函數(shù)名,運(yùn)行,這回是真的ok了。
讀寫.ini文件時(shí),也會(huì)用到dllimport,不過現(xiàn)在.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();
}
}
網(wǎng)上關(guān)于dllimport的很多問題是由于所調(diào)方法的參數(shù)比較復(fù)雜,現(xiàn)在我還沒用到,看到一篇貼子,參數(shù)中帶指針的,也先錄下來,以備將來查用:
參數(shù)是用指針來獲取一個(gè)數(shù)組:int getdata(byte * pbuffer)
pbuffer是數(shù)組的首地址,也就是說getdata會(huì)寫pbuffer[0],pbuffer[1]....pbuffer[100];
答曰:
[dllimport("yourdllfile.dll"]
private static extern int getvalue([marshalas(unmanagedtype.lparray)]byte[] pvalue);
如果是out參數(shù),可以如下
[dllimport("yourdllfile.dll")]
private static extern int getvalue([out,marshalas(unmanagedtype.lparray)]byte[] pvalue);
新聞熱點(diǎn)
疑難解答
圖片精選