1. 托管代码与非托管代码

在学习DllImport方法之前,先了解下托管代码和非托管代码的概念。

我们编写的C#代码(不只是C#,也包括.net平台上的其他语言,如VB,J#等),首先经过编译器把代码编译成中间语言(IL),当方法被调用时,公共语言运行库CLR把具体的方法编译成适合本地计算机运行的机器码,并且将编译好的机器码缓存起来,以备下次调用使用。

托管代码的源代码在运行时分为两个阶段:

  • 源代码编译为托管代码,(源代码可以有很多种,如VB,C#,J#)
  • 托管代码编译为microsoft的平台专用语言,也叫机器代码

非托管代码,是运行在公共语言运行库环境的外部,直接编译成目标计算机码,由操作系统直接执行的代码,代码必须自己提供垃圾回收,类型检查,安全支持等服务。如需要内存管理等服务,必须显示调用操作系统的接口,通常调用Windows SDK所提供的API来实现内存管理。

托管代码和非托管代码的区别

1、托管代码是一种中间语言,运行在CLR上;非托管代码被编译为机器码,运行在机器上。

2、托管代码独立于平台和语言,能更好的实现不同语言平台之间的兼容;非托管代码依赖于平台和语言。

3、托管代码可享受CLR提供的服务(如安全检测、垃圾回收等),不需要自己完成这些操作;非托管代码需要自己提供安全检测、垃圾回收等操作。

2.Dll文件的使用

DLL文件是动态链接库,也叫程序集,是一个包含可由多个程序,同时使用的代码和数据的库。

程序集是在 .NET 公共语言运行库 (CLR) 控制之下运行的逻辑功能单元。程序集实际上是作为 .dll 文件或 .exe 文件存在的。

托管代码生成的DLL文件,可以在VS中直接通过添加引用的方式使用。

非托管代码生成的DLL文件,比如使用C++编写的代码编译生成的DLL,不能在VS中直接引用,可以通过DllImport方法来使用。

3.DllImport的基本使用

DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出函数的必要调用信息。

其中,引入到C#中的只能是非托管dll中的方法(或者说函数),而不能是数据(或者说变量)

(1)引入命名空间

using System.Runtime.InteropServices;

(2)创建函数名称

[DllImport("demo.dll")]
public static extern bool OpenDemo();

其中:

修饰符static和extern是必不可少的(extern外部修饰符,常与DllImport属性一起使用,用于支持在外部实现方法)

最少要提供包含入口点的dll的名称

(3)DllImportAttribute属性用法

[AttributeUsage(AttributeTargets.Method)]
public class DllImportAttribute: System.Attribute
{public DllImportAttribute(string dllName) {…}    //定位参数为dllNamepublic CallingConvention CallingConvention;      //入口点调用约定public CharSet CharSet;                              //入口点采用的字符接public string EntryPoint;                //入口点名称public bool ExactSpelling;               //是否必须与指示的入口点拼写完全一致,默认falsepublic bool PreserveSig;                 //方法的签名是被保留还是被转换public bool SetLastError;                //FindLastError方法的返回值保存在这里public string Value { get {…} }
}

4.DllImport详解

DllImport的使用规范:

(1)DllImport只能放置在方法声明上。
(2)DllImport具有单个定位参数:指定包含被导入方法的 dll 名称的 dllName 参数。
(3)DllImport具有五个命名参数:
 a、CallingConvention 参数指示入口点的调用约定。如果未指定 CallingConvention,则使用默认值 CallingConvention.Winapi。
 b、CharSet 参数指示用在入口点中的字符集。如果未指定 CharSet,则使用默认值 CharSet.Auto。
 c、EntryPoint 参数给出 dll 中入口点的名称。如果未指定 EntryPoint,则使用方法本身的名称。
 d、ExactSpelling 参数指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配。如果未指定 ExactSpelling,则使用默认值 false。
 e、PreserveSig 参数指示方法的签名应当被保留还是被转换。当签名被转换时,它被转换为一个具有 HRESULT 返回值和该返回值的一个名为 retval 的附加输出参数的签名。如果未指定 PreserveSig,则使用默认值 true。
 f、SetLastError 参数指示方法是否保留 Win32"上一错误"。如果未指定 SetLastError,则使用默认值 false。
(4)它是一次性属性类。
(5)此外,用 DllImport 属性修饰的方法必须具有 extern 修饰符。

Dll引用路径

(1)exe运行程序所在的目录

(2)System32目录

(3)环境变量目录

(4)自定义路径,如:DllImport(@"C:\OJ\Bin\Judge.dll")

C#的DllImport使用方法详解相关推荐

  1. python统计csv行数_对Python 多线程统计所有csv文件的行数方法详解

    如下所示: #统计某文件夹下的所有csv文件的行数(多线程) import threading import csv import os class MyThreadLine(threading.Th ...

  2. python修改文件内容_Python批量修改文本文件内容的方法详解

    这篇文章主要介绍了Python批量修改文本文件内容的方法的相关资料,需要的朋友可以参考下 Python批量替换文件内容,支持嵌套文件夹 import os path="./" fo ...

  3. python二维元组_python中读入二维csv格式的表格方法详解(以元组/列表形式表示)

    如何去读取一个没有表头的二维csv文件(如下图所示)? 并以元组的形式表现数据: ((1.0, 0.0, 3.0, 180.0), (2.0, 0.0, 2.0, 180.0), (3.0, 0.0, ...

  4. Spring JdbcTemplate方法详解

    2019独角兽企业重金招聘Python工程师标准>>> Spring JdbcTemplate方法详解 标签: springhsqldbjava存储数据库相关sql 2012-07- ...

  5. golang 解析php序列化,golang实现php里的serialize()和unserialize()序列和反序列方法详解...

    Golang 实现 PHP里的 serialize() . unserialize() 安装 go get -u github.com/techleeone/gophp/serialize 用法 pa ...

  6. ES5和ES6数组遍历方法详解

    ES5和ES6数组遍历方法详解 在ES5中常用的10种数组遍历方法: 1.原始的for循环语句 2.Array.prototype.forEach数组对象内置方法 3.Array.prototype. ...

  7. linux expect 输入密码,shell脚本无密码登录 expect的使用方法详解

    shell脚本无密码登录 expect的使用方法详解 今天需要做一个定时任务脚本将最新的数据包文件传到远程的服务器上,虽然有密钥但也是要求输入密码的那种,所以只能另想办法实现让脚本自动输入密码了. 从 ...

  8. 饥荒怎么自动订阅服务器,饥荒联机版自动挂礼物mod及使用方法详解

    饥荒联机版中官方经常会推出一些挂机掉落礼物的活动,可能一些玩家会觉得很麻烦,下面给大家分享一些自动挂礼物mod和其使用方法,希望可以帮助到各位玩家. 饥荒联机版自动挂礼物mod及使用方法详解 挂礼物m ...

  9. linux oracle 用户创建,LINUX下Oracle数据库用户创建方法详解

    本文实例分析了LINUX下Oracle数据库用户创建方法.分享给大家供大家参考,具体如下: 1)登录linux,以oracle用户登录(如果是root用户登录的,登录后用 su - oracle命令切 ...

最新文章

  1. 分析JDK源码 | Java Object
  2. xcode 中的iOS模拟器,home键快捷键
  3. 如何正确遍历删除List中的元素,你会吗?
  4. duilib 自带树形控件的认识
  5. C++ 实例化对象 p-printX()
  6. gitlab mysql启动不了_gitlab不支持mysql,这就是我学习PostgreSQL的原因
  7. 【struts2】struts2拦截器
  8. Javascript基础之-强制类型转换(一)
  9. (vue基础试炼_03)使用vue.js实现TodoList
  10. bmp转换tiff c++代码_如何快速转换图片格式
  11. 蓝牙 MultipeerConnectivity
  12. 一行代码扫出“敬业福”
  13. 计算机的拓扑 树状结构图,树型网络拓扑结构
  14. 工行u盾显示316_工行网银客户端检测不到U盾的解决方法
  15. 九宫格拼图,避免不可还原
  16. 《Web安全攻防》学习笔记
  17. java map putall 覆盖_Java HashMap putAll() 方法
  18. MuMu模拟器 安装电脑本地apk
  19. G001-181-08
  20. 面试时关于“工作可预见困难有哪些”应聘者如何巧妙回答

热门文章

  1. 由于连接方在一段时间后没有正确答复或连接的主机没有反应_电动车锂电池正确充电方法及充电过程详解...
  2. GPS 入门 10 ——GPS快速定位之AGPS、EPO
  3. 使用PIL的Image.fromarray报错KeyError: ((1, 1, 1), ‘|u1‘)
  4. g++ stray 错误
  5. 2021年 Android Studio 下载安装教程(详细)
  6. linux体验服务器,LINUX架设服务器的初级体验
  7. Maven基础-01-笔记
  8. 燧原科技2021年AI芯片研发工程师笔试
  9. 我要高分飘过PMP!总浮动时间TF和自由浮动时间FF的差别是!!!!!!!
  10. 密码学实验6 维吉尼亚密码