using a structure data from C function returning pointer to struct

  • Thread starter Thread starter vladimir
  • Start date Start date
V

vladimir

Hi, i have big subsystem written in old C and published by dll (and lib). Dll
functions do:
1) allocate global memory for internal structures
2) controls dll subsystem (communicate by sockets, read a files, etc). These
control functions triggers change of a values in the subsystem internal
structures.
3) dealocate memory for internal structures.

Application only processes values in the internal structures, addressed by
pointer returned as result of dll function.

Now, I need write .NET application in C# which use old DLL subsystem. But, I
can not find the way to make accessible the values of subsystem's internal
structures. InteropServices and Marshal functions fails for converting
returned IntPtr to structure. Is there some way to solve this problem ? Thank
for help.
------------------------------------
Declarations in the old C DLL library:
typedef struct my_data_rec{
unsigned char type; // offset 0, length 1
unsigned short len; // offset 2, length 2 (default align 2 on WORD
boundary)
unsigned short elem; // offset 4, length 2
char fill[2];// 2 bytes - force alignment on double boundary
char value[65520];// ASCIZ string variable length
} MY_DATA_STRUCT;
MY_DATA_STRUCT * __cdecl SomeDllFunc();

Application in C# (in class Form1) declarations:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MY_DATA_STRUCT
{
[MarshalAs(UnmanagedType.I1)]
public byte typ;
[MarshalAs(UnmanagedType.U2)]
public ushort len;
[MarshalAs(UnmanagedType.U2)]
public ushort elem;
[MarshalAs(UnmanagedType.I1, SizeConst = 2)]
public string fill; // only 2 bytes, value ignored
[MarshalAs(UnmanagedType.I1, SizeConst = 65520)]
public string textValue;
}
[DllImport("Select.dll", CharSet = CharSet.Auto, CallingConvention =
CallingConvention.Cdecl)]
static extern IntPtr SomeDllFunc();

Application code (in button1_Click procedure):
MY_DATA_STRUCT ReturnedData = new MY_DATA_STRUCT();
IntPtr p;

p = SomeDllFunc();
Marshal.PtrToStructure(p,ReturnedData); // runtime error occurs here in
the moment of the calling

Error reported is some as : "Structure can't be class of values"
 
Tom Shelton said:
Hi, i have big subsystem written in old C and published by dll (and lib). Dll
functions do:
1) allocate global memory for internal structures
2) controls dll subsystem (communicate by sockets, read a files, etc). These
control functions triggers change of a values in the subsystem internal
structures.
3) dealocate memory for internal structures.

Application only processes values in the internal structures, addressed by
pointer returned as result of dll function.

Now, I need write .NET application in C# which use old DLL subsystem. But, I
can not find the way to make accessible the values of subsystem's internal
structures. InteropServices and Marshal functions fails for converting
returned IntPtr to structure. Is there some way to solve this problem ? Thank
for help.
------------------------------------
Declarations in the old C DLL library:
typedef struct my_data_rec{
unsigned char type; // offset 0, length 1
unsigned short len; // offset 2, length 2 (default align 2 on WORD
boundary)
unsigned short elem; // offset 4, length 2
char fill[2];// 2 bytes - force alignment on double boundary
char value[65520];// ASCIZ string variable length
} MY_DATA_STRUCT;
MY_DATA_STRUCT * __cdecl SomeDllFunc();

Application in C# (in class Form1) declarations:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MY_DATA_STRUCT
{
[MarshalAs(UnmanagedType.I1)]
public byte typ;
[MarshalAs(UnmanagedType.U2)]
public ushort len;
[MarshalAs(UnmanagedType.U2)]
public ushort elem;
[MarshalAs(UnmanagedType.I1, SizeConst = 2)]
public string fill; // only 2 bytes, value ignored
[MarshalAs(UnmanagedType.I1, SizeConst = 65520)]
public string textValue;
}
[DllImport("Select.dll", CharSet = CharSet.Auto, CallingConvention =
CallingConvention.Cdecl)]
static extern IntPtr SomeDllFunc();

Application code (in button1_Click procedure):
MY_DATA_STRUCT ReturnedData = new MY_DATA_STRUCT();
IntPtr p;

p = SomeDllFunc();
Marshal.PtrToStructure(p,ReturnedData); // runtime error occurs here in
the moment of the calling

Error reported is some as : "Structure can't be class of values"

You can't use that overload of PtrToStructure for value types. You need to
change that to:

MY_DATA_STRUCT ReturnData = (MY_DATA_STRUCT)Marshal.PtrToStructure (p, typeof(MY_DATA_STRUCT));


Also, I would change your CharSet declarations to Ansi rather then Auto.
Tom, thank you for your suggestion ! It works well.
Vladimir
 
Back
Top