使用平台调用

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. 从零开始的 Python 爬虫速成指南

    序 本文主要内容:以最短的时间写一个最简单的爬虫,可以抓取论坛的帖子标题和帖子内容. 本文受众:没写过爬虫的萌新. 入门 0.准备工作 需要准备的东西: Python.scrapy.一个IDE或者随便 ...

  2. TScrollBox响应鼠标滚轮问题

    Delphi的TScrollBox本身并不响应鼠标滚轮事件(不知道为什么),但可以在ScrollBox的鼠标滚动事件中进行控制: procedure TfrmTaskNoteEdit.ScrollBo ...

  3. 主流ETL(Extract-Transform-Load)工具选型,Kettle Spoon、Datastage、Powercenter介绍

    参考:三大主流ETL工具选型 ETL工具 Kettle Spoon 开源ETL工具,所以免费,用java开发的. Ascential公司的Datastage(在2005年被IBM收购现在是 IBM 的 ...

  4. Quartz2之入门示例

    环境:XP+Myeclipse6.5+JDK1.6 quartz官网:http://www.quartz-scheduler.org/ 参考资料 1 Quartz任务调度快速入门 http://www ...

  5. 【js】批量判断表单中的文本框非空

    方法一: <script type=”text/javascript”> /* * 批量验证表单非空 * 需要非空验证控件的样式class=”mustadd” */ $(".mu ...

  6. RHEL7 -- NetworkManager

    RHEL7中默认的网络服务是由NetworkManager提供,NetworkManager可以动态控制和配置网络. 网络工具和应用 应用或工具 描述 NetworkManager 默认的网络守护进程 ...

  7. OCR 介绍文章

    光学字符识别技术:让电脑像人一样阅读 微软亚洲研究院,霍强: https://www.msra.cn/zh-cn/news/features/ocr-20150720 文章,我们应该做什么样的研究 h ...

  8. mysql 更新数据表的记录

    对于表里的记录值,可以通过update 命令进行更改,语法如下: UPDATE tablename SET field1=value1,field2.=value2,……fieldn=valuen [ ...

  9. Sublime Text 3 快捷鍵

    /*On OS X, basic text manipulations (left, right, command+left, etc) make use of the system key bind ...

  10. iOS自定义组与组之间的距离以及视图

    iOS自定义组与组之间的距离以及视图 //头视图高度 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(N ...