看了P/Invoke技术的介绍,于是想写下点东西,东西包含两个部分:知识的纪录和我的理解及疑问。

r托管代码中调用非托管API函数的过程

  1、定位包含API的DLL;

  2、载入DLL

  3、找到DLL中想要的那个API,然后把参数压入栈中、排列数据(排列数据是什么意思?数据封送)

  4、把执行权限从托管代码中转移到非托管代码中()

对Dll中的函数进行一些说明,以能调用

  DllImport特性来说明函数,有一些特殊的作用,比如换掉API的原来名字,见DLLImport特性。

非托管函数和托管方法中数据类型对应:数据封送

  把C#中数据转换成API中数据类型,是数据封送。对于每个 .NET Framework 类型均有一个默认非托管类型,公共语言运行库将使用此非托管类型在托管到非托管的函数调用中封送数据。string 类型默认非托管类型是LPTSTR,可以在非托管函数的 C# 声明中使用 MarshalAs 属性重写默认封送处理。例如:

    [DllImport("msvcrt.dll")]
public static extern int puts(
[MarshalAs(UnmanagedType.LPStr)]
string m);
puts 函数的参数的默认封送处理已从默认值 LPTSTR 重写为 LPSTR

修改默认封送有什么用?   默认情况下,本机结构和托管结构在内存中的布局有所不同,因此,若要跨托管/非托管边界成功传递结构,需要执行一些额外步骤来保持数据的完整性。,

如果某个API中使用一个结构,那么C#中没有一个对应的托管类型与之对应的话,怎么办?需要为用户定义的结构指定自定义封送处理。

可以为传递到非托管函数或从非托管函数返回的结构和类的字段指定自定义封送处理属性。通过向结构或类的字段中添加 MarshalAs 属性可以做到这一点。还必须使用 StructLayout 属性设置结构的布局,还可以控制字符串成员的默认封送处理,并设置默认封装大小。

C++中:

 struct SS
{   int a;   byte b; }

对应C#中:

 class SS
{
public int a;
public byte b;
}

封送,在此看来算是传数据,但是为什么要封送呢?封送是为了在托管内存和非托管内存中正常传递数据。?有时,出于对性能的考虑,会对托管结构的成员进行重新排列,因此有必要使用 StructLayoutAttribute 特性指示该结构为顺序布局。 将结构封装设置显式设置为与本机结构所使用的设置相同的设置也是一个好办法。

数据封送--基本数据类型对应关系:

数据封送中指针处理的两种情况 :

一、普通指针

  在C#中使用ref out来实行封送。

二、Handle类型

  C#中使用IntPtr来进行封送

  封送,我的理解是两个方面,封装和传送。传送就像是方法中参数的传递那样;而封装就有些意思了,在封装前有时候需要做一些处理。就像是上面的 class SS和C++中的struct  ss ,其实两者中的数据a、b在内存中是不一样的。详细如下:

 
  class SS
{
public int a;
public byte b;
}

  看起来a是在b的前面,其实在内存中可不是这样的,C#中类的字段成员的顺序在内存中是自动安排的,也就是说不像是源代码中那样,至于是为什么是自动(auto)安排顺序,还不知道,希望有人知道的话说一下,而在C++中类成员的顺序却是和看到的一样的,这就是为什么在封装前要做一些处理了,因为成员在内存中的顺序不一样!

C#中有一个特性可以调整这个顺序,也就是[StructLayout(LayoutKind.Sequential)],在没有显式进行修饰一个类时,默认情况下是[StructLayout(LayoutKind.Auto)]的。处理如下:

[StructLayout(LayoutKind.Sequential)]
class SS
{
public int a;
public byte b;
}

注册回调方法

  遇到回调函数的处理。

.NET学习之路----我对P/Invoke技术的理解(一)的更多相关文章

  1. Qt 学习之路:模型-视图高级技术

    PathView PathView是 QtQuick 中最强大的视图,同时也是最复杂的.PathView允许创建一种更灵活的视图.在这种视图中,数据项并不是方方正正,而是可以沿着任意路径布局.沿着同一 ...

  2. 1.typescirpt学习之路,*.d.ts和@types关系理解

    今天看了看ts,文档上很多没用讲,小编疑惑了很久一个问题! *.d.ts和@types啥关系,小编查阅了很多文档,才弄明白. 首先,@types是npm的一个分支,我们把npm包发上去,npm包就会托 ...

  3. 微服务框架surging学习之路——序列化 (转载https://www.cnblogs.com/alangur/p/10407727.html)

    微服务框架surging学习之路——序列化   1.对微服务的理解 之前看到在群里的朋友门都在讨论微服务,看到他们的讨论,我也有了一些自己的理解,所谓微服务就是系统里的每个服务都 可以自由组合.自由组 ...

  4. 『NiFi 学习之路』简介

    『NiFi 学习之路』简介 『NiFi 学习之路』入门 -- 下载.安装与简单使用 『NiFi 学习之路』资源 -- 资料汇总 『NiFi 学习之路』把握 -- 架构及主要组件 『NiFi 学习之路』 ...

  5. RPC远程过程调用学习之路(一):用最原始代码还原PRC框架

    RPC: Remote Procedure Call 远程过程调用,即业务的具体实现不是在自己系统中,需要从其他系统中进行调用实现,所以在系统间进行数据交互时经常使用. rpc的实现方式有很多,可以通 ...

  6. [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. jQuery学习之路(1)-选择器

    ▓▓▓▓▓▓ 大致介绍 终于开始了我的jQuery学习之路!感觉不能再拖了,要边学习原生JavaScript边学习jQuery jQuery是什么? jQuery是一个快速.简洁的JavaScript ...

  8. Android开发学习之路-RecyclerView滑动删除和拖动排序

    Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...

  9. webService学习之路(三):springMVC集成CXF后调用已知的wsdl接口

    webService学习之路一:讲解了通过传统方式怎么发布及调用webservice webService学习之路二:讲解了SpringMVC和CXF的集成及快速发布webservice 本篇文章将讲 ...

随机推荐

  1. 设置共享,实现Linux和Windows之间的共享

    设置共享,实现Linux和Windows之间的共享 前提: 安装虚拟机.可以参考:在Windows上安装虚拟机详细图文教程 安装Linux.可以参考:在VMware Workstation里的Linu ...

  2. cookie实现记住密码

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  3. Azure机器学习入门(一)

    我们开始深入学习Azure机器学习的基本原理并为您开启伟大的数据科学之门.Azure 机器学习的一个重要特征就是在构建预测分析方案时,它能够方便地将开发模式集成为可重复的工作流模式.这就使得Azure ...

  4. 在线倍增法求LCA专题

    1.cojs 186. [USACO Oct08] 牧场旅行 ★★   输入文件:pwalk.in   输出文件:pwalk.out   简单对比时间限制:1 s   内存限制:128 MB n个被自 ...

  5. 【Python网络编程】利用Python进行TCP、UDP套接字编程

    之前实现了Java版本的TCP和UDP套接字编程的例子,于是决定结合Python的学习做一个Python版本的套接字编程实验. 流程如下: 1.一台客户机从其标准输入(键盘)读入一行字符,并通过其套接 ...

  6. php配置参数.md

    php 5.5 配置文件 php.ini Options user_ini.filename string 设定了 PHP 会在每个目录下搜寻的文件名:如果设定为空字符串则 PHP 不会搜寻.默认值是 ...

  7. git教程链接

    http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

  8. C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 检查版本升级、检查登录超时

    当用户都在一个公司内,甚至一个办公室时,喉一下或者跑过去亲自更新一下程序,就可以了,问题就很简单也没多少复杂性,也不怎么考验技术能力.当面对全国10万以上客户端时,问题就来了. 1:有的用户打开系统一 ...

  9. MYSQL的卸载

    卸载mysql 1.查找以前是否装有mysql 命令:rpm -qa|grep -i mysql 可以看到mysql的两个包: mysql-4.1.12-3.RHEL4.1 mysqlclient10 ...

  10. eclipse的几个快捷键

    Alt / 自动补全 Ctrl Shift F 整理代码 Ctrl / 注释或取消注释 Ctrl 鼠标移到变量或类名上 转到声明/实现的接口/返回类型等 Ctrl Shift O import所有缺失 ...