By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,496 Members | 1,266 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,496 IT Pros & Developers. It's quick & easy.

using a structure data from C function returning pointer to struct

P: n/a
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"
-------------------------------------------------------------------
Where is a error in my code fragment, or the solution of the problem do not
exists ? Thank you for your idee.

Jun 27 '08 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On 2008-06-20, vladimir <vl******@discussions.microsoft.comwrote:
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"
-------------------------------------------------------------------
Where is a error in my code fragment, or the solution of the problem do not
exists ? Thank you for your idee.
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 Shelton
Jun 27 '08 #2

P: n/a
"Tom Shelton" wrote:
On 2008-06-20, vladimir <vl******@discussions.microsoft.comwrote:
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"
-------------------------------------------------------------------
Where is a error in my code fragment, or the solution of the problem do not
exists ? Thank you for your idee.

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 Shelton
Tom, thank you for your suggestion ! It works well.
Vladimir
Jun 27 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.