我有一个包含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;
我需要帮助。
答案 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
中间步骤,只需使用指针。