平台调用P-INVOKE(一)--(基础篇)
来源:互联网 发布:淘宝客服售后话术大全 编辑:程序博客网 时间:2024/05/18 01:35
平台调用技术(P/Invoke): 主要用于处理在托管代码中调用C/C++库函数及Win32 API函数等非托管函数的情形
一、基本要素
一个简单例子:
C++声明:
extern "C" __declspec(dllexport) int Multiply(int factorA, int factorB);实现:int Multiply(int factorA, int factorB){return factorA * factorB;}
托管代码(C#)调用此非托管声明:class Invoker{//声明非托管函数[DllImport("Interop.dll",EntryPoint = "Multiply",CharSet = CharSet.Ansi)]static extern int Multiply(int factorA, int factorB);}
总结: (声明托管函数)
1.函数声明:
extern修饰符和static修饰符
2.DllImport属性 (常用)
指定动态库:指明平台要调用的dll名称,此项不可缺少。
指定入口点:EntryPoint 字段按名称或序号指定 DLL 函数,可以使用与原dll中不同名称,不填此项,默认为跟原函数名称一致。
指定字符集:CharSet 字段控制字符串封送处理并确定平台调用在 DLL 中查找函数名的方式。有窄版本 (ANSI) 和宽版本 (Unicode)。MSDN如下说明:
成员名称 说明 Ansi以多字节字符串的形式封送字符串。 Auto针对目标操作系统适当地自动封送字符串。在 Windows NT、Windows 2000、Windows XP 和 Windows Server 2003 系列上默认值为 Unicode;在 Windows 98 和 Windows Me 上默认值为 Ansi。尽管公共语言运行库默认值为 Auto,使用语言可重写此默认值。例如,默认情况下,C# 将所有方法和类型都标记为 Ansi。 None此值已过时,它与 CharSet.Ansi 具有相同的行为。 Unicode以 Unicode 2 字节字符形式封送字符串。
指定调用约定:CallingConvention字段指定调用在非托管代码中实现的方法所需的调用约定。动态链接库导出的一般有两种调用协议,__stdcall和_cdecl。__cdecl是C/C++和MFC程序默认使用的调用约定:采用__cdecl约定时,函数参数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。__stdcall调用约定用于调用Win32 API函数。采用__stdcal约定时,函数参数按照从右 到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定。MSDN如下说明:
成员名称 说明 Cdecl调用方清理堆栈。这使您能够调用具有 varargs 的函数(如 Printf),使之可用于接受可变数目的参数的方法。 FastCall不支持此调用约定。 StdCall被调用方清理堆栈。这是使用平台 invoke 调用非托管函数的默认约定。 ThisCall第一个参数是 this 指针,它存储在寄存器 ECX 中。其他参数被推送到堆栈上。此调用约定用于对从非托管 DLL 导出的类调用方法。 Winapi此成员实际上不是调用约定,而是使用了默认平台调用约定。例如,在 Windows 上默认为 StdCall,在 Windows CE.NET 上默认为 Cdecl。
3、注意事项:
指定动态库:指明平台要调用的dll名称,此项不可缺少。
指定入口点:EntryPoint 字段按名称或序号指定 DLL 函数,可以使用与原dll中不同名称,不填此项,默认为跟原函数名称一致。
指定字符集:CharSet 字段控制字符串封送处理并确定平台调用在 DLL 中查找函数名的方式。有窄版本 (ANSI) 和宽版本 (Unicode)。MSDN如下说明:
指定调用约定:CallingConvention字段指定调用在非托管代码中实现的方法所需的调用约定。动态链接库导出的一般有两种调用协议,__stdcall和_cdecl。__cdecl是C/C++和MFC程序默认使用的调用约定:采用__cdecl约定时,函数参数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。__stdcall调用约定用于调用Win32 API函数。采用__stdcal约定时,函数参数按照从右 到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定。MSDN如下说明:
3、注意事项:
参 数个数、顺序、类型必须保持“等价”一致,函数名称和参数名称可以不一致。
- 平台调用P-INVOKE(一)--(基础篇)
- 平台调用P-INVOKE(一)--(基础篇)
- 平台调用P-INVOKE(一)--(基础篇)
- P/Invoke (平台调用)
- P/Invoke平台调用
- 平台调用P/INVOKE
- P/Invoke (平台调用)
- C#调用C++ 平台调用P/Invoke 调用约定【一】
- P/Invoke平台调用技术
- 平台调用P-INVOKE高级篇(一)--(封送含有二维数组的结构体)
- 平台调用P-INVOKE高级篇(一)--(封送含有二维数组的结构体)
- 平台调用P-INVOKE高级篇(一)--(封送含有二维数组的结构体)
- 未托管资源-平台调用(P/Invoke)
- 使用平台调用(P/Invoke)
- .NET平台调用(Win32 P/Invoke)
- C#中的平台调用(P/Invoke)
- 平台调用P/Invoke进阶 -- 初阶:认识平台调用P/Invoke
- 平台调用P/Invoke进阶 -- 初阶:认识平台调用P/Invoke
- 软件开发中常见的十大系统瓶颈
- 软件测试总结(三)
- private继承与复合
- 访问数据库数据过大:java.lang.OutOfMemoryError: Java heap space :设置jvm虚拟机heap大小
- 移动互联网人:创业、投资、冷暖自知
- 平台调用P-INVOKE(一)--(基础篇)
- 串口通信-MSComm控件使用详解
- 【数据结构】二叉树,以前序序列输入
- httpd.exe: Syntax error on line 129 of D:/ApaServ/Apache2.2/conf/httpd.conf
- DLL中调用约定和名称修饰
- 一个简单的Cucumber+Capybara的BDD开发例子
- 用IE浏览器调试ocx,进不了断点
- linux下mysql命令
- eclipse远程调试