使用平台调用

P/Invoke。它的全名叫平台调用(platform invoke)。用于调用dll 中实现的非托管的单调(flat)编程接口。被称为使用C或C++ 调用约定(calling conventions)。最有名的样例是Win32 编程接口,这是一个巨大的库,它公开了Windows 全部的内置功能。

为了调用单调的非托管编程接口,必须首先定义准备调用的函数。可以分成两步:第一步。用System.Runtime.InteropServices 命名空间下的 DllImport 特性(attribute),可以定义包括想导入函数的 .dll,加上一些其它的可选特性;第二步,用keywordextern。加以 C 风格函数调用的签名,这样。指定了返回类型为F# 类型,和函数的名字,最后是用括号括起来的參数类型和參数名。结果这个函数就能像外部的.NET 方法一样进行调用。

以下的样例演示了怎样导入Windows 函数MessageBeep,并调用:

open System.Runtime.InteropServices



// declare a function found in an external dll

[<DllImport("User32.dll")>]

extern boolMessageBeep(uint32 beepType)



// call this method ignoring the result

MessageBeep(0ul) |> ignore

注意

使用平台调用,最棘手的问题就是要找出要调用函数的签名。在http://pinvoke.net 站点上有 C# 和 VB .NET 中经常使用编程接口的签名的清单。F# 中须要的签名也相类似。这个站点是一个维基百科(wiki),因此能够自由加入 F# 签名。

以下的代码演示了怎样使用平台调用。目标函数期望一个指针,有关设置指针须要注意几点。当定义函数时,须要在类型名字的后面加星号(*)。表示传递指针;在函数调用之前。还要定义一个可变标识符,表示指针指向的内存区域,它可能不是全局的,可是在顶层,必须是函数定义的一部分。

这就是为什么定义函数main,标识符status 是函数定义的一部分;最后,必须使用地址运算符(&&),保证传递给函数的是指针而不是值本身。

提示

编译这段代码总是有警告,由于使用了地址运算符(&&)。要抑制这个警告。能够使用编译器开关--nowarn 51,或者命令#nowarn 51。

openSystem.Runtime.InteropServices

// declare a function found in an external dll

[<DllImport("Advapi32.dll")>]

extern boolFileEncryptionStatus(string filename, uint32* status)

let main() =

//declare a mutable idenifier to be passed to the function

let
mutable status = 0ul

// call thefunction, using the address of operator with the

// secondparameter

FileEncryptionStatus(@"C:\test.txt", && status) |>ignore

printfn"%d" status

main()

这个样例的执行结果例如以下(如果在 C: 盘根文件夹下有一个文件test.txt,加过密的):

1ul

注意

平台调用也能够执行在 Mono 平台上,语法与 F# 中的全然一样。而难点在于保证要调用的库在全部的目标平台上都可用,且遵循在全部不同的平台上库的不同的命名约定。很多其它有关解释的细节,请看http://www.mono-project.com/Interop_with_Native_Libraries上的文章。

DllImport 特性有一些实用的函数。可以设置用来控制怎样调用非托管的函数。表 14-1 做了汇总。

表 14-1 DllImport 上实用的特性

 

特性名

描写叙述

CharSet

定义了传送字符串数据的字符集,能够是 CharSet.Auto、CharSet.Ansi、CharSet.Unicode

EntryPoint

设置调用函数的名字。

假设没有给定名字,那么。keyword extern 后面的名字就作为默认定义的函数名。

SetLastError

这是一个逻辑值。指定是否遇到不论什么错误都应该传送,因此,通过调用 Marshell.GetLastWin32Error() 方法检查可用性。

注意

由于有 COM 组件。没有等价的.NET 的非托管编程接口的数量在持续降低,因此。在准备调用函数前检查一下是否有等价的托管函数。一般会节省大量时间。

使用平台调用(P/Invoke)的更多相关文章

  1. 在 C# 中通过 P/Invoke 调用Win32 DLL

    在 C# 中通过 P/Invoke 调用Win32 DLL 发布日期 : 1/13/2005 | 更新日期 : 1/13/2005 Jason Clark 下载本文的代码: NET0307.exe ( ...

  2. Net调用非托管代码(P/Invoke与C++InterOP) [转]

    将 System::String 转换为 wchar_t* 或 char* PtrToStringChars将String转换为本机wchar_t *或char *.由于 CLR 字符串为内部 Uni ...

  3. .NET Framework 框架的一些简单介绍

    20世纪90年代以来出现的3种典型的组件技术: 1)OMC(对象组件模型)的CORBA2)Microsoft的COM/DCOM3)Sun公司的JavaBeans 在2002年,微软发布了.NET框架的 ...

  4. cefglue埋坑记录

    很少写博客,写的不好,请多多包含,主要是记录工作中的一些问题,和园子里朋友一起讨论学习. 写埋坑记录之前,我先介绍下为什么会使用这个webkit内核的浏览器组件,我是wpf项目使用富文本编辑器,话说w ...

  5. Silverlight之OOB模式下的一些事

    本文简介: 1.为什么要使用OOB?使用OOB的作用? 2.如何实现OOB模式 3.对OOB进行一些设置: 4.检测OOB的安装状态: 5.更新应用程序: 6.WebBrowser控件: 7.桌面通知 ...

  6. 在C#中使用 Win32 和其他库

    C# 用户经常提出两个问题:“我为什么要另外编写代码来使用内置于 Windows® 中的功能?在框架中为什么没有相应的内容可以为我完成这一任务?”当框架小组构建他们的 .NET 部分时,他们评估了为使 ...

  7. C# API 大全

    C:\ProgramFiles\MicrosoftVisual Studio .NET\ FrameworkSDK\Samples\ Technologies\ Interop\PlatformInv ...

  8. .NET Framework基本概念

    http://blog.csdn.net/T573029173/article/details/41730101 .NET是微软的新一代技术平台.对技术人员来说,想真正了解什么是.NET,须先了解.N ...

  9. C#中一些默认的预定义属性

    C#中一些默认的预定义属性,见下表: 预定义的属性 有效目标 说明 AttributeUsage Class 指定另一个属性类的有效使用方式 CLSCompliant 全部 指出程序元素是否与CLS兼 ...

随机推荐

  1. XP和Win 7双系统安装说明和注意事项

    安装前说明: 1.先装XP,再装Windows 7,最好不要反过来,不然XP不会把Windows 7的启动管理器给覆盖掉,会麻烦些.总之遵循“旧版本到新版本”安装原则. 2.如果分区不够大,请用以下软 ...

  2. APP流氓大法之apk 静默安装

    老大要我弄个自动更新,要用到静默安装,网上找到了些大拿的代码,我拿去改吧改吧,先贴出来: /** * 软件静默安装 * @param apkAbsolutePath apk文件所在路径 * @retu ...

  3. Report_SRW工具的基本用法(概念)

    2014-05-31 Created By BaoXinjian

  4. Workflow_工作流的基本概念(概念)

    2014-06-01 Created By BaoXinjian

  5. Android笔记(十)ListView

    ListView是Android中最经常使用的控件之中的一个,也是最难用的控件. ListView的作用是展示大量的数据,只是ListView并非直接和数据打交道.而是通过适配器作为中间桥梁. 1.首 ...

  6. HDU 5402(Travelling Salesman Problem-构造矩阵对角最长不相交路径)

    Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (J ...

  7. 如何在virtualenv虚拟环境中安装mysql-python

    接触过virtualenv后,想在这个虚拟环境中安装独立的开发环境.在安装MySQLdb时遇到错误 pc 09:09:30 File "/home/pc/work/VENV/py3/loca ...

  8. Ubuntu下python两个版本的切换

    最近在Ubuntu16.04安装了python3.5还有系统自带的python2.7.13,总结一下不同版本的切换问题. alias:别名 bashrc:个人配置文件 一.修改Python版本(针对用 ...

  9. ev3dev :利用ssh登录系统

    ev3dev是在debian 8 的基础上修改的,主页上只介绍了利用usb连接系统后,ssh登录的方法. 可是我想用wifi连接到网络后,用ssh登录,非usb线连接. ev3dev的默认用户名为:r ...

  10. git使用(一)----git安装

    windows安装git msysgit是windows版本的Git 下载地址:https://git-for-windows.github.io/ 安装步骤 linux安装git https://g ...