C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
来源:互联网 发布:好用的乳液推荐知乎 编辑:程序博客网 时间:2024/05/19 17:52
一、DLLImport的使用
using System.Runtime.InteropServices; //命名空间
//用DllImport导入Win32的MessageBox函数
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
//方法被声明为static。这是P/Invoke方法所要求的,因为在该Windows API中没有一致的实例概念。接下来,还要注意该方法被标记为extern。这是提示编译器该方法是通过一个从DLL导出的函数实现的,因此不需要提供方法体。
(managed code)
简单点说,托管代码是microsoft的中间语言,他主要的作用是在.NET FRAMEWORK的CLR执行代码前去编译源代码,也就是说托管代码充当着翻译的作用,源代码在运行时分为两个阶段:
1.源代码编译为托管代码;(所以源代码可以有很多种,如VB,C#)
2.托管代码编译为microsoft系统的.net平台专用文件(如类库、可执行文件等)。
三、非托管代码 (unmanaged code)
在公共语言运行库环境的外部,由操作系统直接执行的代码。非托管代码必须提供自己的垃圾回收、类型检查、安全支持等服务;它与托管代码不同,后者从公共语言运行库中获得这些服务。
四、DLLImportAttribute 的字段
字段
说明
BestFitMapping
启用或禁用最佳匹配映射。
.CallingConvention
指定用于传递方法参数的调用约定。 默认值为 WinAPI,该值对应于基于 32 位 Intel 的平台的 __stdcall。
CharSet
控制名称重整以及将字符串参数封送到函数中的方式。 默认值为 CharSet.Ansi。
.EntryPoint
指定要调用的 DLL 入口点。
ExactSpelling
控制是否应修改入口点以对应于字符集。 对于不同的编程语言,默认值将有所不同。
PreserveSig
控制托管方法签名是否应转换成返回 HRESULT 并且返回值有一个附加的 [out, retval] 参数的非托管签名。
默认值为 true(不应转换签名)。
SetLastError
允许调用方使用 Marshal.GetLastWin32Error API 函数来确定执行该方法时是否发生了错误。 在 Visual Basic 中,默认值为 true;在 C# 和 C++ 中,默认值为 false。
ThrowOnUnmappableChar
控件引发的异常,将无法映射的 Unicode 字符转换成一个 ANSI"?"字符。
Entrypoint:
以下列出了重命名 DLL 函数的可能原因:
1.避免使用区分大小写的 API 函数名
2.符合现行的命名标准
3.提供采用不同数据类型的函数(通过声明同一 DLL 函数的多个版本)
4.简化对包含 ANSI 和 Unicode 版本的 API 的使用
如果函数在方法定义中的名称与入口点在 DLL 的名称相同,则不必用 EntryPoint 字段来显式地标识函数
CharSet
SetLastError
SetLastError 错误处理非常重要,但在编程时经常被遗忘。当您进行 P/Invoke 调用时,也会面临其他的挑战 — 处理托管代码中 Windows API 错误处理和异常之间的区别。
如果您正在使用 P/Invoke 调用 Windows API 函数,而对于该函数,您使用 GetLastError 来查找扩展的错误信息,则应该在外部方法的 DllImportAttribute 中将 SetLastError 属性设置为 true。这适用于大多数外部方法。
这会导致 CLR 在每次调用外部方法之后缓存由 API 函数设置的错误。然后,在包装方法中,可以通过调用类库的 System.Runtime.InteropServices.Marshal 类型中定义的 Marshal.GetLastWin32Error 方法来获取缓存的错误值。我的建议是检查这些期望来自 API 函数的错误值,并为这些值引发一个可感知的异常。对于其他所有失败情况(包括根本就没意料到的失败情况),则引发在 System.ComponentModel 命名空间中定义的 Win32Exception,并将 Marshal.GetLastWin32Error 返回的值传递给它。
补充
P/Invoke 方法:
如果 Dotfuscator 检测到 P/Invoke 方法(即本机平台方法)名称被用于查找对应的本机函数,则该名称不会自动重命名。通过别名或序号映射到本机函数的 P/Invoke 方法可以重命名。
Dotfuscator是VS里面一个自带的.NET 混淆器和压缩器,它可以帮助您防止您的应用程序被 反编译。同时,它还可以使得您的应用程序更加小巧以及高效。
- C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
- C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
- C# DllImport 系统调用使用详解、托管代码的介绍、EntryPoint的使用
- C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
- C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
- C# DllImport 托管代码的介绍 EntryPoint的使用
- C#使用DllImport调用非托管的代码
- 在VS2010上使用C#调用非托管C++生成opencv代码的DLL文件
- C#调用非托管的代码
- C# 中托管的使用
- c#的dllimport使用方法详解
- c#的dllimport使用方法详解
- c#的dllimport使用方法详解
- C#中使用DllImport调用C++dll
- c# 如何使用DllImport
- C#直接使用DllImport外部Dll的方法
- C#直接使用DllImport外部Dll的方法
- DllImport调用系统DLL的方法
- Path之玩出花样(PathMeasure)
- 1、Spring boot 体验第一篇 simple demo one
- android下使用gdb 调试方法
- Resharper Color identifiers颜色显示异常解决
- uncaught syntaxerror unexpected identifier
- C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
- 10个经典的 Java main 方法面试题
- 三种方法计算黄金分割数-java代码
- 关于@property定义的属性和大括号里定义的属性的区别
- 可以显示百分比和文件大小的Progressbar
- Window 程序的堆和栈
- java泛型之泛型方法。
- 学习spark之基础环境搭建
- 错误编号