我开始努力解决这个问题。我已经搜索并寻求帮助,但我尝试过的一切似乎都不起作用。我显然做错了什么。
无论如何 - 我将 ac# 结构定义为:
public struct TestStruct
[StructLayout(LayoutKind.Sequential)]
{
public int num;
public IntPtr intArrayPtr;
}
在我的 c# 代码的主体中,我有:
public class Testing
{
[DllImport("testing.dll")]
static extern void Dll_TestArray(out IntPtr intArrayPtr);
public GetArray()
{
IntPtr structPtr = IntPtr.Zero;
TestStruct testStruct;
structPtr = Marshal.AllocHGlobal(Marshal.SizeOf(testStruct));
Marshal.StructureToPtr(testStruct, structPtr, false);
Dll_TestArray(structPtr);
testStruct = (TestStruct) Marshal.PtrToStructure(structPtr, typeof(TestStruct));
}
}
所以现在是 c++ 部分。从结构开始:
struct TestStruct
{
public:
int num;
int* intArray;
}
现在的功能:
extern "C" __declspec(dllexport) void Dll_TestArray(TestStruct *&testStruct)
{
int num = 15;
testStruct->num = num;
testStruct->intArray = new int[num];
for (int i = 0; i < num; i++)
testStruct->intArray[i] = i+1;
}
所以 - 我遇到的问题是,当我将结构恢复到 c# 中时,我的结构不是它应该的样子。我可以看到 num 字段已正确填写:它显示 15。但是,仍然设置为零的是 IntPtr。在 c++ 中完成的数组创建尚未传递到 c#。
如果我尝试退后一步,然后返回 dll 函数,我可以看到数组创建正常并且仍然保留信息。
因此,结构中的 c# intptr 没有设置为在 c++ 中创建的指针(如果有意义的话)。
所以我的问题真的是 - 如何使这项工作正常工作?
我希望能够从 dll 中取回,这是一个包含我需要的所有信息的结构。也就是说,在这个例子中,元素的数量和指向数组的指针。这样,我就可以在 intptr 上执行 Marshal.Copy 来获取数组。
如果有其他方法可以做到这一点,我很乐意这样做。我已经尝试了几种方法,但无济于事。这包括在 c# 中尝试以下结构(其中包含 int 数组,而不是 intptr):
public struct TestStruct
{
public int num;
// i have tried various methods to marshal this- eg:
// [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_I4]
public int[] intArray;
}
而且我还尝试通过引用本身而不是 intptr 传递结构。对此问题的任何帮助将不胜感激。我无法更改 c++ 代码,但可以更改 c# 代码。