看了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. Vim快捷键记录(工作中遇到)

    一 移动类 1. 移动到文件首行 gg 2. 移动到文件末行 G 3. 移动到当前屏首行 H 4. 移动到当前屏末行 L 二 编辑类 1. 替换字符 r 2. 删除字符 x 3. 撤销编辑(还原被修改 ...

  2. 交互式makefile

    之前一直不知道在shell中调用read赋值后,怎么传给makefile中的变量,后来才恍然大悟. myname := $(shell read -p "Enter your name:&q ...

  3. MongoDB学习笔记(一:常见问题汇总)

    一.安装时出现The default storage engine 'wiredTiger' is not available问题解决 今晚在自己老式笔记本来试了一下MongoDB的安装,由于配置比较 ...

  4. 遍历List集合,删除符合条件的元素

    List集合的遍历有三种方式:增强for循环,普通for循环,Iterator迭代器遍历 如果只是对集合进行遍历,以上三种循环都可正常遍历: (1)增强For循环遍历List集合 List<St ...

  5. HashMap实现原理及源码分析

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...

  6. Android(Linux)线路规程的使用

        一般来说,车载导航主机都需要外接若干个UART的外设,如支持HFP的蓝牙模块.与原车通信的CAN解码盒模块.u-blox的GPS模块和DVD机芯等.早年使用Telechips TCC8902+ ...

  7. STL 堆

    洛谷P3378 [模板]堆 #include <iostream> #include <cstdio> #include <algorithm> #include ...

  8. UVA计数方法练习[3]

    UVA - 11538 Chess Queen 题意:n*m放置两个互相攻击的后的方案数 分开讨论行 列 两条对角线 一个求和式 可以化简后计算 // // main.cpp // uva11538 ...

  9. HashMap,Hashtable,TreeMapMap

    package com.wzy.list; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterato ...

  10. Reverse Nodes in k-Group

    Reverse Nodes in k-Group Given a linked list, reverse the nodes of a linked list k at a time and ret ...