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

时间:2022-09-01 15:53:50

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