用C ++到C#结构设置变量

时间:2015-01-15 09:41:35

标签: c# c++-cli

我有一个包含3个项目的解决方案。一个C#WinForms项目依赖于第二个项目,它是一个C ++ DLL。 C ++ DLL依赖于第三个项目,它是一个静态库。静态库是带有C ++类的C代码。 DLL充当C代码和C#代码之间的互操作。

我需要通过C#结构设置静态库使用的变量。

我没有C ++ / CLI方面的经验(我已经开始阅读了。网上发现的例子对我来说没有意义)

到目前为止,我已经在C#中创建了一个结构。我创建了一个初始化的非托管内存来保存这个结构:

IntPtr ptData = Marshal.AllocHGlobal(Marshal.SizeOf(objMyClass.data));//data is the structure I am initializing in the constructor of MyClass
Marshal.StructureToPtr(objPythonInterop.data, ptData, false);
objCPPClass.UpdateData(ptData);//objCPPClass is object to class in DLL. libClass is the object of class in static library

这是我在C#中的结构:

[StructLayout(LayoutKind.Sequential)]
public struct Data
{
    members here..
}

在DLL中,这是UpdateData函数:

部首:

void UpdateData(IntPtr ptrData);

来源:

void CPPClass::UpdateData(IntPtr ptrData)
{
    m_lib->UpdateDataInLib(ptrData);// m_lib is object to class in static library
}

UpdateDataInLib是静态库中的类中的一个函数。如何在此函数中使用ptrData并更新变量?我在静态库中有一个类似于我的C#代码中定义的结构的结构。如何将ptr转换为此结构并访问成员?

我的C ++静态库中有一个结构,它包含C#中结构的等效成员:

extern "C"  __declspec(dllexport) typedef struct Data
{
    members here..
}Data, *pData;

我需要帮助。

1 个答案:

答案 0 :(得分:1)

这是一种更简单的方法。如果您的DLL在调用之后不再访问该结构,则不需要动态内存分配。只需将结构放在堆栈上(尽管如此仍然需要fixed):

var data = new objMyClass.data
{
    field1 = value1, // etc
};

unsafe
{
    fixed (objMyClass.data* ptr = &data)
    {
        objCPPClass.UpdateData(new IntPtr(ptr));
    }
}

如果结构是长寿的,那么保持你的代码原样,但不要忘记释放已分配的内存。

然后,在C ++方面,你可以直接投射:

void CPPClass::UpdateData(IntPtr ptrData)
{
    m_lib->UpdateDataInLib(static_cast<pData>(ptrData.ToPointer()));
}

但由于我不知道UpdateDataInLib的签名,我不确定这种做法。

此外,您可以摆脱IntPtr中间步骤,只需使用指针。