using a structure data from C function returning pointer to struct

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"
 
V

vladimir

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
 

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