Need help regarding marshaling
-
Hi all, in my C# app I have to call a function in a legacy Win32 DLL. This function fills a complex struct. Unfortunately, I don't know how to port the data structure to .NET. Here's a simple example:
public class Test
{
[StructLayout(LayoutKind.Sequential)]
public class Test
{
int i;
}\[StructLayout(LayoutKind.Sequential)\] public class Test2 { \[MarshalAs(UnmanagedType.ByValArray, SizeConst=10)\] public Test1\[\] tests; } public Test() { int size = Marshal.SizeOf(typeof(Test2)); }
}
In the constructor,
Marshal.SizeOf
throws the exception Type Test2 can not be marshaled as an unmanaged structure; no meaningful size or offset can be computed. How do I marshal fixed size arrays of struct properly? Thanks in advance. Regards Thomas
Disclaimer:
Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you. -
Hi all, in my C# app I have to call a function in a legacy Win32 DLL. This function fills a complex struct. Unfortunately, I don't know how to port the data structure to .NET. Here's a simple example:
public class Test
{
[StructLayout(LayoutKind.Sequential)]
public class Test
{
int i;
}\[StructLayout(LayoutKind.Sequential)\] public class Test2 { \[MarshalAs(UnmanagedType.ByValArray, SizeConst=10)\] public Test1\[\] tests; } public Test() { int size = Marshal.SizeOf(typeof(Test2)); }
}
In the constructor,
Marshal.SizeOf
throws the exception Type Test2 can not be marshaled as an unmanaged structure; no meaningful size or offset can be computed. How do I marshal fixed size arrays of struct properly? Thanks in advance. Regards Thomas
Disclaimer:
Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.First, those need to be
struct
s. Second, you may need to specify the Test1 struct size, not just the number of elements. If you expect a variable number of elements, you should look at the SizeParam(?) property of theMarshalAsAttribute
to specify the index of a member that specifies the number of elements in the struct array.
Reminiscent of my younger years... 10 LOAD "SCISSORS" 20 RUN
-
First, those need to be
struct
s. Second, you may need to specify the Test1 struct size, not just the number of elements. If you expect a variable number of elements, you should look at the SizeParam(?) property of theMarshalAsAttribute
to specify the index of a member that specifies the number of elements in the struct array.
Reminiscent of my younger years... 10 LOAD "SCISSORS" 20 RUN
Heath Stewart wrote: First, those need to be structs. Ok, but it doesn't help at the moment. Heath Stewart wrote: Second, you may need to specify the Test1 struct size, not just the number of elements. If you expect a variable number of elements, you should look at the SizeParam(?) property of the MarshalAsAttribute to specify the index of a member that specifies the number of elements in the struct array. It's fixed sized, therefore I used
SizeConst
. :confused: Thanks anyway. Regards Thomas
Disclaimer:
Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you. -
Heath Stewart wrote: First, those need to be structs. Ok, but it doesn't help at the moment. Heath Stewart wrote: Second, you may need to specify the Test1 struct size, not just the number of elements. If you expect a variable number of elements, you should look at the SizeParam(?) property of the MarshalAsAttribute to specify the index of a member that specifies the number of elements in the struct array. It's fixed sized, therefore I used
SizeConst
. :confused: Thanks anyway. Regards Thomas
Disclaimer:
Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.I had the same problem and the only way is to Marshal it as a byte[] array and not the encapsulating class. If the class has more members, things become a bit more difficult. MyDUMeter: a .NET DUMeter clone
-
I had the same problem and the only way is to Marshal it as a byte[] array and not the encapsulating class. If the class has more members, things become a bit more difficult. MyDUMeter: a .NET DUMeter clone
leppie wrote: If the class has more members, things become a bit more difficult. In fact, the structurs are cascaded about three levels X| Regards Thomas
Disclaimer:
Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you. -
leppie wrote: If the class has more members, things become a bit more difficult. In fact, the structurs are cascaded about three levels X| Regards Thomas
Disclaimer:
Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.I think it is time for a Custom Marshaller. You need to implement this interface.
public interface ICustomMarshaler
{
public void CleanUpManagedData(object ManagedObj);
public void CleanUpNativeData(IntPtr pNativeData);
public int GetNativeDataSize();
public IntPtr MarshalManagedToNative(object ManagedObj);
public object MarshalNativeToManaged(IntPtr pNativeData);
}And set MarshalAs(UnmanagedType.CustomMarshaler) on the class. From there you should havenough control to marshal just about anything. Note: You can now make classes without Layout. Cheers :) MyDUMeter: a .NET DUMeter clone
-
I think it is time for a Custom Marshaller. You need to implement this interface.
public interface ICustomMarshaler
{
public void CleanUpManagedData(object ManagedObj);
public void CleanUpNativeData(IntPtr pNativeData);
public int GetNativeDataSize();
public IntPtr MarshalManagedToNative(object ManagedObj);
public object MarshalNativeToManaged(IntPtr pNativeData);
}And set MarshalAs(UnmanagedType.CustomMarshaler) on the class. From there you should havenough control to marshal just about anything. Note: You can now make classes without Layout. Cheers :) MyDUMeter: a .NET DUMeter clone
leppie wrote: I think it is time for a Custom Marshaller. :omg: Ok, it's an opportunity to learn something new ;) BTW, I am not the only one with this problem: http://www.dotnet247.com/247reference/msgs/28/141537.aspx[^] Regards Thomas
Disclaimer:
Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.