学习C# DllImport相关知识

开发 后端
本文通过一些详细的例子介绍了C# DLLImport的相关内容,希望对大家有所帮助。

MSDN中对DllImport Attribute的解释是这样的:可将该属性应用于方法。DllImport Attribute 属性提供对从非托管 DLL 导出的函数进行调用所必需的信息。作为***要求,必须提供包含入口点的 DLL 的名称。

并给了一个示例:

  1. [DllImport("KERNEL32.DLL", EntryPoint="MoveFileW", SetLastError=true,  
  2.  
  3. CharSet=CharSet.Unicode, ExactSpelling=true,  
  4.  
  5. CallingConvention=CallingConvention.StdCall)]  
  6.  
  7. public static extern bool MoveFile(String src, String dst); 

上网搜了一下,最常见的就是使用它来调用WIN32的API,例如上面所示。或者调用一下C或C++编写的DLL。

这东西没怎么用过。只是前几天忽然分配下一个临时的任务,做一个“停车厂管理”的小东西,听说是一个大干部的小孩子要弄这么个东西,那干部是公司的客户,讨论正经事之余又拜托了我们做这么个小东西。其中用到了单片机模拟车辆出入的一些信号。

我对单片机一窍不通,好在有人写好了轮询单片机的DLL,我只管调用,由于是C++写的,于是将DLL拷贝到BIN目录后(这DLLImport会从程序启动目录开始查找相应名称的DLL,未找到则转至system32下查找),用DllImport来调用,但在这个过程中遇到了几个问题:

1.看了一下C++的代码,需要用到的只有三个方法:

  1. bool OpenSerialPort1()  
  2.  
  3. bool fnGetIO(unsigned char& P1, unsigned char& P2, unsigned char& P3)  
  4.  
  5. bool CloseSerialPort1() 

于是就在自己的程序中写了:

  1. using System.Runtime.InteropServices;  
  2.  
  3. ……  
  4.  
  5. [DllImport("GetIODll.dll", EntryPoint = "OpenSerialPort1")]  
  6.  
  7. public static extern bool OpenSerialPort1();  
  8.  
  9. [DllImport("GetIODll.dll", EntryPoint = "fnGetIO")]  
  10.  
  11. public static extern bool fnGetIO(ref byte P1, ref byte P2, ref byte P3);  
  12.  
  13. [DllImport("GetIODll.dll", EntryPoint = "CloseSerialPort1")]  
  14.  
  15. 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文件时,也会用到C# DllImport,不过现在.ini文件好像用得少了,下面是读写的程序:

  1. {  
  2.  
  3. publicstring path;  
  4.  
  5. [DllImport("kernel32")]  
  6.  
  7. privatestaticexternlong WritePrivateProfileString(string section,string key,string val,string filePath);  
  8.  
  9. [DllImport("kernel32")]  
  10.  
  11. privatestaticexternint GetPrivateProfileString(string section,string key,string def,StringBuilder  
  12.  
  13. retVal,int size,string filePath);  
  14.  
  15. public IniFile(string INIPath)  
  16.  
  17. {  
  18.  
  19.        path = INIPath;  
  20.  
  21. }  
  22.  
  23. publicvoid IniWriteValue(string Section,string Key,string Value)  
  24.  
  25. {  
  26.  
  27.        WritePrivateProfileString(Section,Key,Value,this.path);  
  28.  
  29. }  
  30.  
  31. publicstring IniReadValue(string Section,string Key)  
  32.  
  33. {  
  34.  
  35.        StringBuilder temp = new StringBuilder(255);  
  36.  
  37.        int i = GetPrivateProfileString(Section,Key,"",temp,255,this.path);  
  38.  
  39.        return temp.ToString();  
  40.  
  41. }  
  42.  

网上关于C# DllImport的很多问题是由于所调方法的参数比较复杂,现在我还没用到,看到一篇贴子,参数中带指针的,也先录下来,以备将来查用:

参数是用指针来获取一个数组:Int GetData(byte * pBuffer) 

pBuffer是数组的首地址,也就是说GetData会写pBuffer[0],pBuffer[1]....pBuffer[100];

答曰:

  1. [DllImport("yourDllFile.dll"]    
  2.  
  3. Private static extern int GetValue([MarshalAs(UnmanagedType.LPArray)]byte[] pValue); 

如果是out参数,可以如下 

  1. [DllImport("yourDllFile.dll")]  
  2.  
  3. Private static extern int GetValue([Out,MarshalAs(UnmanagedType.LPArray)]byte[] pValue); 

 C# DllImport的相关内容就介绍到这里。

【编辑推荐】

  1. 学习C#消息:循序渐进
  2. 解惑答疑:C#委托和事件
  3. 学习C#实现HTTP协议:多线程文件传输
  4. 进一步接触C#委托与事件
  5. 浅析四种C#转换的区别
责任编辑:book05 来源: hi.baidu
相关推荐

2009-08-21 08:41:44

C#反射

2009-09-01 16:14:08

C# Socket类

2009-08-07 13:30:20

C# Excel导入

2009-08-10 14:03:08

C# COM接口

2009-08-13 14:59:00

C#数据访问层

2009-06-12 09:22:44

VB.NET类型C#

2009-09-01 15:25:01

C#位域

2010-01-12 17:54:42

VB.NET Dlli

2009-08-24 17:07:09

C# 泛型

2009-07-30 18:20:21

C#继承

2009-08-27 16:11:03

C# delegateC# event

2009-08-05 18:39:54

C#异常类

2010-03-24 10:54:50

企业私有云

2009-08-13 12:50:45

C#基础知识

2009-08-13 16:13:03

C#基础知识

2009-08-24 11:02:52

C#接口映射

2009-08-27 16:37:06

C#基础知识

2009-09-02 14:06:14

C#文件传送

2009-08-24 09:55:26

C#接口转换

2009-08-05 18:28:05

C#异常处理
点赞
收藏

51CTO技术栈公众号