A
Aston Martin
Hi All,
********************** My Situation **********************
I am working on project that involves passing a structure to unmanaged
code from .Net world (well using C#). Perhaps an example will prove
useful.
structure MyStruct
{
// this is a complicated struct declaration in the sense
that it includes other structures
// (thankfully they are not variable sized) and also a
large array of char
SomeStruct1 member1
SomeStruct2 member2
char bigArray[7664];
};
void foo_get_struct_by_value( MyStruct valStruc );
in managed world I wrote all the required declaration for MyStruct,
SomeStruct1, SomeStruct2 and p-invoke signature of
foo_get_struct_by_value().
let this be the declaration in C#(appended Cs against each type, Cs
stands for well, C# )
structure CsMyStruct
{
CsSomeStruct1 member1
CsSomeStruct2 member2
char bigArray[7664];
};
void cs_foo_get_struct_by_value( MyStruct valStruc );
********************** My Problem **********************
if I try calling cs_foo_get_struct_by_value() MarshalDirectiveException
is being thrown with this message "Internal limitation: structure is
too complex or too large."
********************** My Solution (that didn't work, hence this
post) **********************
Hence I tried using unconventional means to achieve my goal. I cannot
modify the legacy code, it is important to achieve in managed code else
I will have to run around begging for permission to modify the legacy
code.
The idea is to present legacy code with a 'lump' of memory. The legacy
code will interpret it as a valid structure instance. Here is the code
illustrating what I am mean. For this I modified the p-invoke signature
of cs_foo_get_struct_by_value() to as below
cs_foo_get_struct_by_value( byte[] lumpOfMemory );
// allocate a structure and do something with it, fill it with data
etc.
CsMyStruct myStruct = new CsMyStruct();
// save the size, we will need it again
int structSize = Marshal.SizeOf( myStruct );
// allocate memory in unmanaged area
IntPtr ptr = Marshal.AllocHGlobal( structSize );
// get the address of managed structure
Marshal.StructureToPtr( myStruct, ptr, false );
// copy the managed structure contents in 'lump of memory'
byte[] lumpOfMemory = new byte[structSize];
Marshal.Copy( ptr, lumpOfMemory, 0, structSize );
Marshal.FreeHGlobal( ptr );
// let the unmanaged function do its job
cs_foo_get_struct_by_value( lumpOfMemory );
********************** My Situation **********************
I am working on project that involves passing a structure to unmanaged
code from .Net world (well using C#). Perhaps an example will prove
useful.
structure MyStruct
{
// this is a complicated struct declaration in the sense
that it includes other structures
// (thankfully they are not variable sized) and also a
large array of char
SomeStruct1 member1
SomeStruct2 member2
char bigArray[7664];
};
void foo_get_struct_by_value( MyStruct valStruc );
in managed world I wrote all the required declaration for MyStruct,
SomeStruct1, SomeStruct2 and p-invoke signature of
foo_get_struct_by_value().
let this be the declaration in C#(appended Cs against each type, Cs
stands for well, C# )
structure CsMyStruct
{
CsSomeStruct1 member1
CsSomeStruct2 member2
char bigArray[7664];
};
void cs_foo_get_struct_by_value( MyStruct valStruc );
********************** My Problem **********************
if I try calling cs_foo_get_struct_by_value() MarshalDirectiveException
is being thrown with this message "Internal limitation: structure is
too complex or too large."
********************** My Solution (that didn't work, hence this
post) **********************
Hence I tried using unconventional means to achieve my goal. I cannot
modify the legacy code, it is important to achieve in managed code else
I will have to run around begging for permission to modify the legacy
code.
The idea is to present legacy code with a 'lump' of memory. The legacy
code will interpret it as a valid structure instance. Here is the code
illustrating what I am mean. For this I modified the p-invoke signature
of cs_foo_get_struct_by_value() to as below
cs_foo_get_struct_by_value( byte[] lumpOfMemory );
// allocate a structure and do something with it, fill it with data
etc.
CsMyStruct myStruct = new CsMyStruct();
// save the size, we will need it again
int structSize = Marshal.SizeOf( myStruct );
// allocate memory in unmanaged area
IntPtr ptr = Marshal.AllocHGlobal( structSize );
// get the address of managed structure
Marshal.StructureToPtr( myStruct, ptr, false );
// copy the managed structure contents in 'lump of memory'
byte[] lumpOfMemory = new byte[structSize];
Marshal.Copy( ptr, lumpOfMemory, 0, structSize );
Marshal.FreeHGlobal( ptr );
// let the unmanaged function do its job
cs_foo_get_struct_by_value( lumpOfMemory );