Marshal object as a byte array.

  • Thread starter repekto.argosoft
  • Start date
R

repekto.argosoft

Hi,

I'm working with Marshalling. I got an idea to pass an object to the
Native side as a byte array i.e. as void* in terms of C.

For example:

I have a .NET structure Point that contains two fields X and Y that
means that the byte array representation will look in the memory like
this: "XXXXYYYY" First four bytes are X and second for bytes are Y.
Then I marshall this array to the C-style function. I declare this
function in C# code this way:

[DllImport( "ImageProcessor.dll",
CharSet = CharSet.Auto,
EntryPoint = "Uninitialize" )]
private static extern int PassPoint_native(byte[] serializedPoint);

This function is declared on the native part this way:

int PassPoint_native(CPoint* point);

where CPoint class is following:

struct CPoint
{
int X;
int Y;
}

The byte array passed to the function PassPoint will be mapped to the
class CPoint and I get the object in terms of C/C++.

This is a simple example, but I think it can be used in more complex
cases.

Is it possible to represent the C# object as a raw byte array?

Kind regards,
Eugene.
 
G

Guest

Hi,

I'm working with Marshalling. I got an idea to pass an object to the
Native side as a byte array i.e. as void* in terms of C.

For example:

I have a .NET structure Point that contains two fields X and Y that
means that the byte array representation will look in the memory like
this: "XXXXYYYY" First four bytes are X and second for bytes are Y.
Then I marshall this array to the C-style function. I declare this
function in C# code this way:

[DllImport( "ImageProcessor.dll",
CharSet = CharSet.Auto,
EntryPoint = "Uninitialize" )]
private static extern int PassPoint_native(byte[] serializedPoint);

This function is declared on the native part this way:

int PassPoint_native(CPoint* point);

where CPoint class is following:

struct CPoint
{
int X;
int Y;
}

The byte array passed to the function PassPoint will be mapped to the
class CPoint and I get the object in terms of C/C++.

This is a simple example, but I think it can be used in more complex
cases.

Is it possible to represent the C# object as a raw byte array?

Kind regards,
Eugene.

Yes, it's possible, but:

:: You have to pin the object in memory, so that the garbage collector
can't move it around.

:: The object can only contain value type members. It can't contain
references to other objects.

:: The members are not always stored back to back within the object.
There may be padding between the members to align them to suitable
offsets. I'm not sure, but I think that the compiler might also
rearrange members to store them better.
 
M

Mattias Sjögren

I'm working with Marshalling. I got an idea to pass an object to the
Native side as a byte array i.e. as void* in terms of C.

Why? What do you gain by using a byte array rather than the actual
type?

private static extern int PassPoint_native(ref Point p);


Mattias
 
R

repekto.argosoft

:: The members are not always stored back to back within the object.
There may be padding between the members to align them to suitable
offsets. I'm not sure, but I think that the compiler might also
rearrange members to store them better.

This item means that it is impossible to map class members on the
respective place in the native code.
 
R

repekto.argosoft

:: The members are not always stored back to back within the object.
There may be padding between the members to align them to suitable
offsets. I'm not sure, but I think that the compiler might also
rearrange members to store them better.

This item means that it is impossible to map class members on the
respective place in the native code.
 
R

repekto.argosoft

Why? What do you gain by using a byte array rather than the actual
type?

private static extern int PassPoint_native(ref Point p);

I thought it could be useful to marshal non-constant size arrays
wrapped inside of the structure.

struct A
{
int[] arr; // this array may contain different number of
elements,
}

I see only one opportunity to pass it to unmanaged code. It is to
create a managed structure reflecting the native structure like this:

struct A_export
{
IntPtr pArr;
}

and then allocate the memory for pArr using Marshall.AllocHGlobal().
And then copy the array to dynamic memory.

Do you know another procedure to pass such structures to the native
code and retrieve it back to managed?
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

This item means that it is impossible to map class members on the
respective place in the native code.

Practically, yes.

In a structure, you can use attributes to control how the members are
aligned.
 
A

Ananas

Practically, yes.

But in general?
In a structure, you can use attributes to control how the members are
aligned.

Yes, but how to do when you have an unpredictable size of an array as
like in the case that I showed?
 

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