Passing structures between C# and C?

  • Thread starter Thread starter Germic
  • Start date Start date
G

Germic

Hi,

I've never got an answer to this question in any group till now....
How do we pass a array of structures between a C# and a C DLL, I am using
RCW interop?

The C# Library gets an array of structures from a webservice and it has to
pass these values to the C DLL so that the C DLL could parse it and consume
1 structure at a time?
Help!
 
The runtime does not support this, so you have to do it yourself using
Custom marshaling.

Willy.
 
Hi Willy,

Thanks for your reply.. could you pls shed some more light on how to do this?

Regards.
 
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct L_Germplasm
{
public long gdate;
public long gid;
public long glocn; ....etc., around 9 long fields
}

I have to pass an array of such structures to my C program in one hit
(instance).

OR

How do can I hold that array of structures in C# Library itself and then
pass one such structure each time the C DLL contacts the C# Library? How do I
hold and pass the address of the ArrayList or HashTable between the C DLL and
C# Library?

Any suggestions/help to any of the above two questions would be greatly
appreciated.
 
GeRmIc said:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct L_Germplasm
{
public long gdate;
public long gid;
public long glocn; ....etc., around 9 long fields
}

I have to pass an array of such structures to my C program in one hit
(instance).

Ok, there are several way's to marshal such simple array of struct .
Here's one of them:

//C# prog.
[StructLayout(LayoutKind.Sequential)]
struct S
{
internal int a;
internal int b;
internal int c;
internal int d;
}

class Tester
{
[DllImport("nativeStrucArr.dll")]
private static extern void func_c( S[] ao, int len);

static void Main()
{
int elem = 10;
S[] IntArray = new S[elem];
for (int s = 0;s < elem ; s++)
{
IntArray.a = elem - s;
IntArray.b = elem - s;
IntArray.c = elem - s;
IntArray.d = elem - s;
}
// Pass array and number of elements, IntArray is pinned for the duration of
the call only!
func_c( IntArray, IntArray.Length);
}
}

//C program....
struct S
{
int a;
int b;
int c;
int d;
};
// take pointer to void for the array pointer
extern "C" {
__declspec(dllexport) void __stdcall func_c (void * pas, int len);
}

void __stdcall func_c (void * pas, int len)
{
int ret = 0;
S *sa = new S[len]; // allocate array of struct in native heap
S *s = static_cast<S*>(pas); // cast array * to struct *
// copy array of struct elements to new array (native memory)
for (int n = 0; n < len; n++)
{
sa[n].a = (s + n)->a;
sa[n].b = (s + n)->b;
sa[n].c = (s + n)->c;
sa[n].d = (s + n)->d;
}
// Use array when done
// Dump to console for demo
for (int n = 0; n < len; n++)
{
printf_s("Cont %d\n", sa[n].a);
printf_s("Cont %d\n", sa[n].b);
printf_s("Cont %d\n", sa[n].c);
printf_s("Cont %d\n", sa[n].d);
}
}
OR

How do can I hold that array of structures in C# Library itself and then
pass one such structure each time the C DLL contacts the C# Library?
Not sure what you mean with OR.

What exactly do you mean with contacts the C# library?
How do I
hold and pass the address of the ArrayList or HashTable between the C DLL
and
C# Library?

Any suggestions/help to any of the above two questions would be greatly
appreciated.

But it seems like you are looking for something which isn't possible, you
cannot take the address of a managed object and use it as such in unmanaged
code.
That's the whole point of marshaling, a C program has no idea what an
Hashtable is or looks like, so you have to convert the data members to
something that C can understand and use, and that is what marshaling is
about.

Willy.
 
Back
Top