C++/CLI 托管C++之结构体封装(内存对齐#pragma pack)【9】

CLI封装涉及内存对齐的结构体时,使用的是StructLayoutAttribute,指定Pack为1、4、8等属性

【1】C++导出函数,使用 1位对齐

#pragma pack(push)
#pragma pack(1)
typedef struct _testStru2
{
	int		iVal;
	char	cVal;
	__int64 llVal;
}testStru2;
#pragma pack(pop)
//4.2 结构体边界对齐
EXPORTDLL_CLASS void Struct_PackN( testStru2 *pStru )
{
	if (NULL == pStru)
	{
		return;
	}

	pStru->iVal = 1;
	pStru->cVal = 'a';
	pStru->llVal = 2;

	wprintf(L"Struct_PackN \n");
}

CLI封装:

[Serializable]
[StructLayoutAttribute(LayoutKind::Sequential, Pack=1)]
public ref struct test2
{
    Int32	iVal;
    SByte	cVal;
    Int64   llVal;

    void UnmanagedPtr2ManagedStru(IntPtr ptr)
    {
        testStru2 *ptStru = static_cast<testStru2 *>(ptr.ToPointer());
        if (NULL == ptStru)
            return;

        iVal = ptStru->iVal;
        cVal = ptStru->cVal;
        llVal= ptStru->llVal;
    }
};
void ExportCLI::StructCls::StructPackN( test2^ %pStru )
{
    if (pStru == nullptr)
    {
        return;
    }

    testStru2  strT;

    strT.iVal = pStru->iVal;
    strT.cVal = pStru->cVal;
    strT.llVal = pStru->llVal;

    Struct_PackN(&strT);
    pStru->UnmanagedPtr2ManagedStru(IntPtr(&strT));
}

CLI类声明:

/// <summary>
/// 3 结构体测试类
/// </summary>
public ref class StructCls
{
public:
    /// <summary>
    /// 3.1 结构体作为输入输出参数
    /// </summary>
    /// <param name="pStru">结构体</param>
    static void StructChange(test1^ %pStru);
    /// <summary>
    /// 3.2 结构体边界对齐
    /// </summary>
    /// <param name="pStru">结构体</param>
    static  void StructPackN(test2^ %pStru);
    /// <summary>
    /// 3.3 结构体中含有内置数据类型的数组
    /// </summary>
    /// <param name="pStru">结构体</param>
    static  void StructChangeArr(test3^ %pStru);
    /// <summary>
    /// 3.4 union类型中含有结构体
    /// </summary>
    /// <param name="pStru">结构体</param>
    static  void StructUnion(test4^ %pStru);
    /// <summary>
    /// 3.5 结构体数组作为参数
    /// </summary>
    /// <param name="pStru">结构体数组</param>
    static  void StructStruArr(List<test5^>^ pStru);
};

C#测试程序:

可以看到结构体的长度为13.

test2 tStru2 = new test2();
tStru2.iVal  = 0;
tStru2.cVal  = 0;
tStru2.llVal = 0;
int size = Marshal.SizeOf(tStru2.GetType());
StructCls.StructPackN(ref tStru2);

源码地址:

https://coding.net/u/aoshilangCode/p/CLI/git

时间: 2024-10-11 16:50:03

C++/CLI 托管C++之结构体封装(内存对齐#pragma pack)【9】的相关文章

C语言 结构体的内存对齐问题与位域

http://blog.csdn.net/xing_hao/article/details/6678048 一.内存对齐 许多计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对 齐,而这个k则被称为该数据类型的对齐模数(alignment modulus).当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数,我们就称类型S的对齐要求比T强(严格),而称T比S弱(宽 松).这种强制的要求一来简化了处

3.c语音结构体成员内存对齐详解

一.关键一点 最关键的一点:结构体在内存中是一个矩形,而不是一个不规则形状 二.编程实战 1 #include <stdlib.h> 2 #include <stdio.h> 3 4 struct A 5 { 6 int a; 7 char b; 8 }; 9 10 int main() 11 { 12 struct A a; 13 a.a = 1; 14 a.b = 1; 15 printf("%p\n", &a); 16 17 system(&quo

关于结构体占用空间大小总结(#pragma pack的使用)

关于C/C++中结构体变量占用内存大小的问题,之前一直以为把这个问题搞清楚了,今天看到一道题,发现之前的想法完全是错误的.这道题是这样的: 在32位机器上,下面的代码中 class A { public: int i; union U { char buff[13]; int i; }u; void foo(){} typedef char* (*f)(void*); enum{red , green, blue}color; }a; sizeof(a)的值是多少?如果在代码前面加上#pragm

对于结构体中内存对齐的简单说明

结构体内存对齐的原因: 在运行一个结构体时,编译器需要给结构体中的每个变量成员分配内存空间,如这样一个结构体中 typedef struct A { char c1; int i; int j; }A; 对其内存空间分配问题进行分析,如若不进行内存对齐,它的内存空间是: char类型变量c1占1个字节,紧接着int类型变量i与j分别占4个字节,总有9个字节,在访问时,如图1,访问次数较多:在图2中,总有12个字节空间,虽然浪费了c1后的三个字节空间,访问次数却变少,会很大程度上节省了时间,提高了

程序设计基石与实践系列之失落的C语言结构体封装艺术

英文来源于 Eric S. Raymond-- The Lost Art of C Structure Packing 谁该阅读这篇文章 本文是关于削减C语言程序内存占用空间的一项技术--为了减小内存大小而手工重新封装C结构体声明.你需要C语言的基本知识来读懂本文. 如果你要为内存有限制的嵌入式系统.或者操作系统内核写代码,那么你需要懂这项技术.如果你在处理极大的应用程序数据集,以至于你的程序常常达到内存的界限时,这项技术是有帮助的.在任何你真的真的需要关注将高速缓存行未命中降到最低的应用程序里

(转)失落的C语言结构体封装艺术

目录1. 谁该阅读这篇文章 2. 我为什么写这篇文章 3.对齐要求 4.填充 5.结构体对齐及填充 6.结构体重排序 7.难以处理的标量的情况 8.可读性和缓存局部性 9.其他封装的技术 10.工具 11.证明及例外 12.版本履历 1. 谁该阅读这篇文章 本文是关于削减C语言程序内存占用空间的一项技术——为了减小内存大小而手工重新封装C结构体声明.你需要C语言的基本知识来读懂本文. 如果你要为内存有限制的嵌入式系统.或者操作系统内核写代码,那么你需要懂这项技术.如果你在处理极大的应用程序数据集

结构体在内存中的存储方式

结构体在内存中如何存储? 遵循结构体对齐规则: 1.首先要知道默认对齐数:VS 中 8   Linux 中4 2.第一个成员放到0偏移处 3.后面所有的成员都放到对齐数(本身和默认对齐数的较小值)的倍数处偏移 4.结构体总大小为所有对齐数中最大对齐数的倍数 Eg: 运行结果为 24 图中可以看出内存有浪费,而我们将小的成员放一起可以节省资源 减少浪费. 上例可以改为: int i: char c: double d: 这样总大小只需16 节省浪费. 空的结构体类型大小为1,创建对象需要开辟空间,

结构体的内存空间分配及字节对齐

关于内存对齐 一: 1.什么是内存对齐 假设我们同时声明两个变量: char a; short b; 用&(取地址符号)观察变量a, b的地址的话,我们会发现(以16位CPU为例): 如果a的地址是0x0000,那么b的地址将会是0x0002或者是0x0004. 那么就出现这样一个问题:0x0001这个地址没有被使用,那它干什么去了?答案就是它确实没被使用.因为CPU每次都是从以2字节(16位CPU)或是4字节(32位CPU)的整数倍的内存地址中读进数据的.如果变量b的地址是0x0001的话,那

结构体的内存空间分配原理

关于内存对齐 一: 1.什么是内存对齐 假设我们同时声明两个变量: char a; short b; 用&(取地址符号)观察变量a, b的地址的话,我们会发现(以16位CPU为例): 如果a的地址是0x0000,那么b的地址将会是0x0002或者是0x0004. 那么就出现这样一个问题:0x0001这个地址没有被使用,那它干什么去了?答案就是它确实没被使用.因 为CPU每次都是从以2字节(16位CPU)或是4字节(32位CPU)的整数倍的内存地址中读进数据的.如果变量b的地址是0x0001的话,