主要是看默认封送处理行为

按类成员的类型是否为“可直接传递到非托管内存”的类型来分类;按照成员中是否有“可直接传递到非托管内存”的类型来讨论。

  所有成员都是“可直接传递到非托管内存”的类型

  托管代码和非托管代码:

    //托管代码
ClassStruct cs = new ClassStruct();
cs.a = ;
cs.d = ;
DoClassStruct(cs); Console.Read();
} [StructLayout(LayoutKind.Sequential)]
class ClassStruct
{
public int a;
public double d;
}
、、、、、、、、、、、////////////非托管代码
typedef struct
{
    int a;
    double d;
}CLASSSTRUCT; extern "C" __declspec(dllexport) void DoClassStruct(CLASSSTRUCT *cs)
{
    printf("%d\n",cs->a);
    printf("%lf\n",cs->d);
    cs->a=100;
}

  下断点,在DoClassStruct(cs);处,发现cs的地址是0x01bcbaa0;进入 非托管函数中,下断点,发现cs的地址不变。如下:

0x01BCBAA0  5a 00 00 00 00 00 00 00 00 00 00 00 00 00 37 40  Z.............7@   其中的5a是指90,后面8位是指double值23.0 。

  结论:如果类的字段都是“可直接传递到非托管代码中”的类型,那么传递是引用,或者说是指针。这是在非托管代码中的修改也会反映到托管代码中了。这个过程就是锁定。

类的成员不包含“非可直接传递到非托管代码中”的类型

  看下面一个例子,满足条件的类型有bool和string类型等。

            cs.a = ;
cs.d = ;
cs.str = "abcd";
DoClassStruct(cs);
Console.WriteLine(cs.a); Console.Read();
} [StructLayout(LayoutKind.Sequential)]
class ClassStruct
{
public int a;
public double d;
public string str;
}
/////////////////////////////非托管代码
typedef struct
{
int a;
double d;
char *pStr;
}CLASSSTRUCT; extern "C" __declspec(dllexport) void DoClassStruct(CLASSSTRUCT *cs)
{
printf("%d\n",cs->a);
printf("%lf\n",cs->d);
cs->a=;
}

  通过跟踪发现,依然使用普通结构体的过程:在非托管内存中开辟空间---把托管内存中数据复制一份到非托管内存M-----内存M的地址作为参数传递给函数---一切的操作都是围着内存M进行。 可想而知,最后的结果不会反映到托管内存中去。

p/invoke碎片--对类的封送处理的更多相关文章

  1. p/invoke碎片--对数组的封送处理

    因为数组是引用类型,所以数组的处理根据数组元素的类型是否为“可直接传递到非托管代码”的类型而分为两种情况.主要目标是看内存是怎么变化的,是复制还是锁定. 数组中的元素是"可直接传递到非托管代 ...

  2. p/invoke碎片,对结构体的处理

    结构体的一些相关知识 可直接转换类类型,比如int类型,在托管代码和非托管代码中占据内存大小 和意义都是一个样的. 结构体封送的关键是:在托管代码和非托管代码中定义的一致性.什么是定义的一致性?包括结 ...

  3. C#调用C/C++动态库 封送结构体,结构体数组

    一. 结构体的传递 #define JNAAPI extern "C" __declspec(dllexport) // C方式导出函数 typedef struct { int ...

  4. C#调用C/C++动态库 封送结构体,结构体数组

    因为实验室图像处理的算法都是在OpenCV下写的,还有就是导航的算法也是用C++写的,然后界面部分要求在C#下写,所以不管是Socket通信,还是调用OpenCV的DLL模块,都设计到了C#和C++数 ...

  5. C# 互操作性入门系列(三):平台调用中的数据封送处理

    好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...

  6. [转]C# 互操作性入门系列(三):平台调用中的数据封送处理

    参考网址:https://www.cnblogs.com/FongLuo/p/4512738.html C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列( ...

  7. p/invoke 碎片-- 对字符串的处理

    字符串在内存中的的几种风格 字符串作为参数和返回值 参考 字符串在内存中的几种风格 所谓的风格,也就是字符串在内存中的存在形式.如何存放的,占据内存的大小,还有存放顺序等.在不同的编程语言和不同的平台 ...

  8. [原]C#与非托管——封送和自动封送

    之前说到了如何从C函数声明通过简单的查找替换生成一份C#的静态引用声明(C#与非托管——初体验),因为只是简单说明,所以全部采用的是基础类型匹配和自动封送.自动封送虽然能省去我们不少编码时间,但如果不 ...

  9. MarshalAs属性指示如何在托管代码和非托管代码之间封送数据。

    http://blog.csdn.net/tianyu0910/article/details/6260755 http://blog.sina.com.cn/s/blog_4e4ee8ed0100e ...

随机推荐

  1. 【msql】关于redo 和 undo log

    InnoDB 有两块非常重要的日志,一个是undo log,另外一个是redo log,前者用来保证事务的原子性以及InnoDB的MVCC,后者用来保证事务的持久性.和大多数关系型数据库一样,Inno ...

  2. dubox首次调用消费者执行两次问题

    dubbox+zookeeper服务开启后 Dubbo的超时重试机制为服务容错.服务稳定提供了比较好的框架支持,但是在一些比较特殊的网络环境下(网络传输慢,并发多)可能由于服务响应慢,Dubbo自身的 ...

  3. POJ 2398 Toy Storage(计算几何)

    题意:给定一个如上的长方形箱子,中间有n条线段,将其分为n+1个区域,给定m个玩具的坐标,统计每个区域中的玩具个数. 题解:通过斜率判断一个点是否在两条线段之间. /** 通过斜率比较点是否在两线段之 ...

  4. 前端自动化测试 —— TDD环境配置(React+TypeScript)

    欢迎讨论与指导:) 前言 TDD -- Test-Drive Development是测试驱动开发的意思,是敏捷开发中的一项核心实践和技术,也是一种测试方法论.TDD的原理是在开发功能代码之前,先编写 ...

  5. elasticsearch5.0及head插件安装

        这个瞎jb整了半天.准备把es2.4升级到5.0,结果老报错 环境:centos6.5+es2.4是ok的换成es5就出毛病.也不能说啥 ,我用的是最新的 源码解压启动时候报错,具体错误for ...

  6. codevs 2879 堆的判断

    codevs 2879 堆的判断 http://codevs.cn/problem/2879/ 题目描述 Description 堆是一种常用的数据结构.二叉堆是一个特殊的二叉树,他的父亲节点比两个儿 ...

  7. tomcat 8.5.9.0 解决catalina.out过大的问题

    先吐嘈一下tomcat这个项目,日志切割这么常见的功能,tomcat这种知名开源项目默认居然不开启,生产环境跑不了几天,磁盘就满了,而且很多网上流传的方法,比如修改conf/logging.prope ...

  8. 基于C/S架构的3D对战网络游戏C++框架 _05搭建系统开发环境与Boost智能指针、内存池初步了解

    本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...

  9. 数据集偏斜 - class skew problem - 以SVM松弛变量为例

    原文 接下来要说的东西其实不是松弛变量本身,但由于是为了使用松弛变量才引入的,因此放在这里也算合适,那就是惩罚因子C.回头看一眼引入了松弛变量以后的优化问题: 注意其中C的位置,也可以回想一下C所起的 ...

  10. 跨域请求——WebClient通过get和post请求api

    AJAX不可以实现跨域请求,经过特殊处理才行.一般后台可以通过WebClient实现跨域请求~ //get 请求        string url = string.Format("htt ...