zoukankan      html  css  js  c++  java
  • p/invoke碎片--对类的封送处理

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

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

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

      托管代码和非托管代码:

        //托管代码       
                ClassStruct cs = new ClassStruct();
                cs.a = 90;
                cs.d = 23;
                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 ",cs->a);
        printf("%lf ",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 = 90;
                cs.d = 23;
                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
    ",cs->a);
        printf("%lf
    ",cs->d);
        cs->a=100;
    }

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

  • 相关阅读:
    POJ 3041 Asteroids 最小点覆盖 == 二分图的最大匹配
    POJ 3083 Children of the Candy Corn bfs和dfs
    POJ 2049 Finding Nemo bfs 建图很难。。
    POJ 2513 Colored Sticks 字典树、并查集、欧拉通路
    POJ 1013 Counterfeit Dollar 集合上的位运算
    POJ 2965 The Pilots Brothers' refrigerator 位运算枚举
    无聊拿socket写的100以内的加法考试。。。
    POJ 1753 Flip Game
    初学socket,c语言写的简单局域网聊天
    汇编语言 复习 第十一章 标志寄存器
  • 原文地址:https://www.cnblogs.com/ddx-deng/p/3886414.html
Copyright © 2011-2022 走看看