I'm starting to struggle with this problem. I've searched and searched for help, and everything i've tried doesn't seem to work. I'm obviously doing something wrong.
Anyway - i have a c# structure defined as:
public struct TestStruct
[StructLayout(LayoutKind.Sequential)]
{
public int num;
public IntPtr intArrayPtr;
}
and in the main body of my c# code i have:
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));
}
}
So now for the c++ part. Starting with the structure:
struct TestStruct
{
public:
int num;
int* intArray;
}
and now the functions:
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;
}
So - the problem i'm having, is that when i get the structure back into c#, my structure is not how it should be. I can see that the num field has been filled in correctly: it shows 15. However, it is the IntPtr that is still set to zero. The array creation done in c++ has not been carried through to c#.
If i try go step back, and go back into the dll function, i can see that the array was created ok and still retains the information.
So the c# intptr in the struct, is not being set to the pointer being created in c++ (if that makes sense).
So my question really is - how does one make this work correctly?
I want to be able to get back from the dll, a structure which contains all the information that i need. That is, in this example, the number of elements, and the pointer to the array. That way, i can then do a Marshal.Copy on the intptr, to get the array.
If there's another way to do this, i'm more than happy to do it. I've tried several ways already, to no avail. This includes trying the following structure in c# (which contains the int array, rather than the 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;
}
And i've also tried passing the structure by reference itself, rather than an intptr. Any help on this matter would be massively appreciated. I am unable to change the c++ code, but the c# code can be changed.