C++/CLI 托管C++的托管与非托管字符串的相互转换【1】
C++/CLI 托管C++之结构体封装(内存对齐#pragma pack)【9】
CLI封装Union时,没有对应的类型,使用的是结构体struct,指定每个元素的偏移位置。
【1】声明结构体struct时,需要显示指定为Explicit。
【2】每个数据需要使用FieldOffsetAttribute指定偏移位置。
C++导出函数
typedef union _testStru4
{
int iValLower;
int iValUpper;
struct
{
__int64 llLocation;
};
}testStru4;
//4.4 union类型中含有结构体
EXPORTDLL_CLASS void Struct_Union( testStru4 *pStru )
{
if (NULL == pStru)
{
return;
}
pStru->llLocation = 1024;
wprintf(L"Struct_Union \n");
}
CLI封装
[Serializable]
[StructLayoutAttribute(LayoutKind::Explicit)]
public ref struct test4
{
[FieldOffsetAttribute(0)]
Int32 iValLower;
[FieldOffsetAttribute(4)]
Int32 iValUpper;
[FieldOffsetAttribute(0)]
Int64 llLocation;
void UnmanagedPtr2ManagedStru(IntPtr ptr)
{
testStru4 *ptStru = static_cast<testStru4 *>(ptr.ToPointer());
if (NULL == ptStru)
return;
llLocation = ptStru->llLocation;
}
};
void ExportCLI::StructCls::StructUnion( test4^ %pStru )
{
if (pStru == nullptr)
{
return;
}
testStru4 strT;
strT.llLocation = pStru->llLocation;
Struct_Union(&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#测试:可以看到,当给llLocation赋值时,其余iValLower也会自动赋值。
test4 tStru4 = new test4();
tStru4.llLocation = 44444444444;
StructCls.StructUnion(ref tStru4);