How to return array of structs from unmanaged DLL to C#?

D

Darkriser

Mates,
the problem is pretty simple, but I'm unable to manage it... Therefore
asking you for help.

Situation:
Have managed code in C# and unamanged code in C++ DLL.
I need to make a call from C# to a function exported by the DLL.
Moreover, I have following struct (in C# and C++, as well):
struct myStruct {
unsigned int val1;
unsigned int val2;
}

What I need:
The C# function declares two empty variables (one for the array itself and
second one for the number of items returned in the array) and passes them
using "ref" keyword to C++ function. The C++ function determines the number
of array elements that will be returned, dynamically allocates memory,
creates the array of structs and passes it (along with the size of the array
itself) to the C# function.

Assumptions:
- C# code (the calling one) doesn't know the number of items in the array
that will be returned
- C# must NOT use unsafe code
- the number of items in the array may vary, but will always be >0

I know that Marshalling/Serialization will be required, but I can't find the
right code. Below, you can see my current C++ and C# code. I'm able to return
and marshal only 1 element. Any ideas?

// C++ code - currently returns only 1 element
struct test {
unsigned int val1;
unsigned int val2;
};

extern "C" __declspec(dllexport) void Test(test** pArray, int* pSize)
{
*pArray = (test*) CoTaskMemAlloc(sizeof(test) * 1);
for (unsigned int i = 0; i < 1; i++)
{
(*pArray + i)->accountID = i;
(*pArray + i)->period = i+1;
(*pArray + i)->cycle = i+2;
(*pArray + i)->cellType = i+3;
}
*pSize = 1;
}

// C# code
[StructLayout(LayoutKind.Sequential)]
public class clTest
{
public uint val1;
public uint val2;
}

[DllImport("somedll.dll")]
public static extern void Test(out IntPtr tst, ref int pSize);

IntPtr buffer;
int size = 0;

Test(out buffer, ref size);
if (size > 0)
{
clTest arr = new clTest();
Marshal.PtrToStructure(buffer, arr );
Marshal.FreeCoTaskMem(buffer);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top