passing pointer reference to structure with array

T

Tobias

Hi!
I have a problem which is quite tricky.
I need to pass a struct from .NET to a native Win32 DLL.
But i just need to pass the pointer to a reference of that struct.
With my first struct this worked pretty well, accepting to write
unsafe code ;-)
But my next struct has an array inside and I don't get it passed over
to the DLL correctly.

Here my struct in c#:

[StructLayout(LayoutKind.Sequential)]
unsafe public struct SDKNavInfo
{
public System.UInt32 size;
public TSDKPosition Pos;

[..]
//this is the relevant array!!
public System.UInt32[] PreviousManover;

[..]
}

My DLL Import looks like this (this can not be changed by myself):

[DllImport("SDK")]
unsafe private extern static int GetGuidanceInformation(TGPSData *
GPSData, System.Int32 forecast, ref SDKNavInfo *
NavigationInformation);

And this is the corresponding code where I try to call the function:

//method declared unsafe because of use of pointers and reference
private unsafe void btnCalcRoute_Click(object sender, System.EventArgs
e)
{
[..]
SDKNavInfo NavInfo = new SDKNavInfo();

[..]
SDKNavInfo * pNavInfo = &NavInfo;

GetGuidanceInformation(null, 0, ref pNavInfo);
}

Calling the GetGuidanceInformation function results in an error where
the debugger says (sorry for the translation, I get it in german!)
"parameter#3 can not be marshalled. Pointer can not point to
marshalled structures. Use byref instead."

I don't get it...what does it mean? Or even better, how can I fix this
problem??
Thanks in advance for your help :)
cheerz
Tobias
 
N

Nicholas Paldino [.NET/C# MVP]

Tobias,

This is dependent on the original definition of your structure. If the
structure has the array embedded in it, then you can declare the structure
in .NET like this:

[StructLayout(LayoutKind.Sequential)]
unsafe public struct SDKNavInfo
{
public System.UInt32 size;
public TSDKPosition Pos;
//this is the relevant array!!
[MarshalAs(UnmanagedType.ByValArray, SizeOf=10)]
public System.UInt32[] PreviousManover;
}

Notice the SizeOf property on the MarshalAs attribute. This would be
the size of the array as it is defined in the original structure.

Now, if the array is defined as a pointer to an address in memory, then
you will have to marshal that array into unmanaged memory (getting an
IntPtr), and then define the field as an IntPtr and setting it to the
marshaled value.

If you are using unsafe code, then you can just define it as void* and
then get the address of the array and use that. You have to be careful that
the unmanaged code you call doesn't change the value of this pointer, or you
will orphan memory.

Hope this helps.
 

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