关于C#中的DLLImport (引)

简介: MSDN中对DllImportAttribute的解释是这样的:可将该属性应用于方法。DllImportAttribute 属性提供对从非托管 DLL 导出的函数进行调用所必需的信息。作为最低要求,必须提供包含入口点的 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);
上网搜了一下,最常见的就是使用它来调用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);

博客园大道至简

http://www.cnblogs.com/jams742003/

转载请注明:博客园

目录
相关文章
|
Linux
LINUX C#DllImport编译出错怎么办?
LINUX C#DllImport编译出错怎么办?
202 0
|
.NET C# 开发框架
C# DllImport用法和路径问题
DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息。    DllImport属性应用于方法,要求最少要提供包含入口点的dll的名称。
2144 0
C# DllImport的用法
大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法)要重新编写代码,C#有没有方法可以直接都用这些原本已经存在的功能呢?答案是肯定的,大家可以通过C#中的DllImport直接调用这些功能。
1384 0
|
API C#
C#中通过DllImport使用 Win32 API(引)
.net 框架程序可以通过静态 DLL 入口点的方式来访问本机代码库。DllImport 属性用于指定包含外部方法的实现的dll 位置。 DllImport 属性定义如下:    namespace System.
1064 0
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
470 3
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
340 3
|
10月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
200 3
|
9月前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
545 12
|
10月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
397 4
|
安全 程序员 编译器
C#一分钟浅谈:泛型编程基础
在现代软件开发中,泛型编程是一项关键技能,它使开发者能够编写类型安全且可重用的代码。C# 自 2.0 版本起支持泛型编程,本文将从基础概念入手,逐步深入探讨 C# 中的泛型,并通过具体实例帮助理解常见问题及其解决方法。泛型通过类型参数替代具体类型,提高了代码复用性和类型安全性,减少了运行时性能开销。文章详细介绍了如何定义泛型类和方法,并讨论了常见的易错点及解决方案,帮助读者更好地掌握这一技术。
195 11