• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

DLLImport在C#中的用法

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
    上网搜了一下,最常见的就是使用它来调用WIN32的API,例如上面所示。或者调用一下C或C++编写的DLL。 这东西没怎么用过。只是前几 天忽然分配下一个临时的任务,做一个“停车厂管理”的小东西,听说是一个大干部的小孩子要弄这么个东西,那干部是公司的客户,讨论正经事之余又拜托了我们 做这么个小东西。其中用到了单片机模拟车辆出入的一些信号。 
    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);


我 对单片机一窍不通,好在有人写好了轮询单片机的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);

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#线程同步之Moitor实现线程的顺序执行发布时间:2022-07-10
下一篇:
c#编程指南(五)扩展方法(ExtensionMethod)发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap