C++/CLI 托管C++的托管与非托管字符串的相互转换【1】
C++/CLI 托管C++之结构体封装(内存对齐#pragma pack)【9】
【1】结构体作为输入输出参数
C++导出函数:
typedef struct _testStru1
{
int iVal;
char cVal;
__int64 llVal;
}testStru1;
//4.1 结构体作为输入输出参数
EXPORTDLL_CLASS void Struct_Change( testStru1 *pStru )
{
if (NULL == pStru)
{
return;
}
pStru->iVal = 1;
pStru->cVal = 'a';
pStru->llVal = 2;
wprintf(L"Struct_Change \n");
}
CLI封装
[Serializable]
public ref struct test1
{
Int32 iVal;
SByte cVal;
Int64 llVal;
void UnmanagedPtr2ManagedStru(IntPtr ptr)
{
testStru1 *ptStru = static_cast<testStru1 *>(ptr.ToPointer());
if (NULL == ptStru)
return;
iVal = ptStru->iVal;
cVal = ptStru->cVal;
llVal= ptStru->llVal;
}
};
void ExportCLI::StructCls::StructChange( test1^ %pStru )
{
if (pStru == nullptr)
{
return;
}
testStru1 strT;
strT.iVal = pStru->iVal;
strT.cVal = pStru->cVal;
strT.llVal = pStru->llVal;
Struct_Change(&strT);
pStru->UnmanagedPtr2ManagedStru(IntPtr(&strT));
}
c#测试函数:
test1 tStru1 = new test1();
tStru1.iVal = 0;
tStru1.cVal = 0;
tStru1.llVal = 0;
StructCls.StructChange(ref tStru1);
【2】结构体中含有内置数据类型的数组
C++导出函数:
typedef struct _testStru3
{
int iValArrp[30];
WCHAR szChArr[30];
}testStru3;
//4.3 结构体中含有内置数据类型的数组
EXPORTDLL_CLASS void Struct_ChangeArr( testStru3 *pStru )
{
if (NULL == pStru)
{
return;
}
pStru->iValArrp[0] = 8;
lstrcpynW(pStru->szChArr, L"as", 30);
wprintf(L"Struct_ChangeArr \n");
}
CLI封装
[Serializable]
public ref struct test3
{
array<Int32>^ iValArrp;
array<Char>^ szChArr;
test3()
{
iValArrp = gcnew array<Int32>(30);
szChArr = gcnew array<WCHAR>(30);
}
void UnmanagedPtr2ManagedStru(IntPtr ptr)
{
testStru3 *ptStru = static_cast<testStru3 *>(ptr.ToPointer());
if (NULL == ptStru)
return;
for (int ix=0; ix<30; ix++)
{
iValArrp[ix] = ptStru->iValArrp[ix];
szChArr[ix] = ptStru->szChArr[ix];
}
}
};
void ExportCLI::StructCls::StructChangeArr( test3^ %pStru )
{
if (pStru == nullptr)
{
return;
}
testStru3 strT;
for (int ix=0; ix<pStru->iValArrp->Length; ix++)
{
strT.iValArrp[ix] = pStru->iValArrp[ix];
strT.szChArr[ix] = pStru->szChArr[ix];
}
Struct_ChangeArr(&strT);
pStru->UnmanagedPtr2ManagedStru(IntPtr(&strT));
}
C#测试函数:
test3 tStru3 = new test3();
tStru3.iValArrp[0] = 55;
tStru3.szChArr[1] = '1';
StructCls.StructChangeArr(ref tStru3);
【3】结构体数组作为参数、
C++导出函数
typedef struct _testStru5
{
int iVal;
}testStru5;
//4.5 结构体数组作为参数
EXPORTDLL_CLASS void Struct_StruArr( testStru5 *pStru, int len )
{
if (NULL == pStru)
{
return;
}
for ( int ix=0; ix<len; ix++)
{
pStru[ix].iVal = ix;
}
wprintf(L"Struct_StruArr \n");
}
CLI封装
[Serializable]
public ref struct test5
{
Int32 iVal;
test5()
{
iVal = 5;
}
};
void ExportCLI::StructCls::StructStruArr( List<test5^>^ pStru )
{
if (pStru == nullptr)
{
return;
}
int len = pStru->Count;
testStru5 *pStruArr = new testStru5[len];
for (int ix=0; ix<len; ix++)
{
pStruArr[ix].iVal = pStru[ix]->iVal;
}
Struct_StruArr(pStruArr, len);
//内存释放
if (NULL != pStruArr)
{
delete []pStruArr;
pStruArr = NULL;
}
}
C#测试:
List<test5> tStru5 = new List<test5>(0);
tStru5.Add(new test5());
StructCls.StructStruArr(tStru5);
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);
};