马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
前几天同学问我学习方向的问题。有点想法,不知道对不对,怕误导同学,现在“开源一下”。注:括号内是我现在整理的时填加上的。MSDN中对DllImportAttribute的注释是如许的:可将该属性使用于办法。DllImportAttribute属性供应对从非托管DLL导出的函数举行挪用所必须的信息。作为最低请求,必需供应包括出口点的DLL的称号。
并给了一个示例:
[DllImport("KERNEL32.DLL",EntryPoint="MoveFileW",SetLastError=true,
CharSet=CharSet.Unicode,ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
publicstaticexternboolMoveFile(Stringsrc,Stringdst);
上彀搜了一下,最多见的就是利用它来挪用WIN32的API,比方下面所示。大概挪用一下C或C++编写的DLL。
这器材没怎样用过。只是头几天溘然分派下一个一时的义务,做一个“泊车厂办理”的小器材,传闻是一个年夜干部的小孩子要弄这么个器材,那干部是公司的客户,会商正派事之余又奉求了我们做这么个小器材。个中用到了单片机摹拟车辆收支的一些旌旗灯号。
我对单片机一无所知,幸亏有人写好了轮询单片机的DLL,我尽管挪用,因为是C++写的,因而将DLL拷贝到BIN目次后(这DLLImport会从程序启动目次入手下手查找响应称号的DLL,未找到则转至system32下查找),用DllImport来挪用,但在这个过程当中碰到了几个成绩:
1.看了一下C++的代码,必要用到的只要三个办法:
boolOpenSerialPort1()
boolfnGetIO(unsignedchar&P1,unsignedchar&P2,unsignedchar&P3)
boolCloseSerialPort1()
因而就在本人的程序中写了:
usingSystem.Runtime.InteropServices;
……
[DllImport("GetIODll.dll",EntryPoint="OpenSerialPort1")]
publicstaticexternboolOpenSerialPort1();
[DllImport("GetIODll.dll",EntryPoint="fnGetIO")]
publicstaticexternboolfnGetIO(refbyteP1,refbyteP2,refbyteP3);
[DllImport("GetIODll.dll",EntryPoint="CloseSerialPort1")]
publicstaticexternboolCloseSerialPort1();
但是程序在运转时不管怎样老是提醒“找不到出口点”,弄得懵了,只好上彀搜往,最初下了一个叫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文件仿佛用得少了,上面是读写的程序:
{
publicstringpath;
[DllImport("kernel32")]
privatestaticexternlongWritePrivateProfileString(stringsection,stringkey,stringval,stringfilePath);
[DllImport("kernel32")]
privatestaticexternintGetPrivateProfileString(stringsection,stringkey,stringdef,StringBuilder
retVal,intsize,stringfilePath);
publicIniFile(stringINIPath)
{
path=INIPath;
}
publicvoidIniWriteValue(stringSection,stringKey,stringValue)
{
WritePrivateProfileString(Section,Key,Value,this.path);
}
publicstringIniReadValue(stringSection,stringKey)
{
StringBuildertemp=newStringBuilder(255);
inti=GetPrivateProfileString(Section,Key,"",temp,255,this.path);
returntemp.ToString();
}
}
网上关于DllImport的良多成绩是因为所调办法的参数对照庞大,如今我还没用到,看到一篇贴子,参数中带指针的,也先录上去,以备未来查用:
参数是用指针来猎取一个数组:IntGetData(byte*pBuffer)
pBuffer是数组的首地点,也就是说GetData会写pBuffer[0],pBuffer[1]....pBuffer[100];
答曰:
[DllImport("yourDllFile.dll"]
PrivatestaticexternintGetValue([MarshalAs(UnmanagedType.LPArray)]byte[]pValue);
假如是out参数,能够以下
[DllImport("yourDllFile.dll")]
PrivatestaticexternintGetValue([Out,MarshalAs(UnmanagedType.LPArray)]byte[]pValue);
c++是语言,其实C++和java的应用范围根本就不一样的。在java应用的领域内,c++是不合适的。所以微软才搞了C#和Java对抗。 |