passing address of a Managed float array to unamaged DLL

  • Thread starter Thread starter dbru
  • Start date Start date
D

dbru

I need to pass an address of a Managed float array to a DLL. The
following doesn't seem to work


[DllImportAttribute("xx32_.DLL", CharSet=CharSet.Auto)]
extern static float GetXXX([MarshalAs(UnmanagedType.LPStr)]
StringBuilder HWND,
[MarshalAs(UnmanagedType.U8)] long nWhat,
[MarshalAs(UnmanagedType.LPArray)] ref float[] lparam
);

.......


float[] fMeasValues = new float[256];
ifRtn = GetXXX(null, WAVELENGTH, ref fWaveLengths);

Regards,

Dan
 
Dan,

What is the original declaration of the function?

Also, you won't need the CharSet property in the DllImport attribute if
you are specifying the type of the string as LPStr specifically.

If you want a pointer to the array, then you can just use what you have.

However, if you want the pointer to the pointer which is the array
itself, then you will need to use IntPtr and marshal yourself, like this:

[DllImportAttribute("xx32_.DLL", CharSet=CharSet.Auto)]
extern static float GetXXX(
[MarshalAs(UnmanagedType.LPStr)]
StringBuilder HWND,
[MarshalAs(UnmanagedType.U8)] long nWhat,
[MarshalAs(UnmanagedType.LPArray)] ref IntPtr lParam);


The reason for this is that if you need a double-pointer, then your
array is being allocated in the function itself. You need the value of the
pointer upon return so that you can free the memory (since the P/Invoke
layer doesn't know how it is allocated, it can't de-allocate it).

Then, to get your float array, you start with the lParam parameter
(which is set to the array beginning now), and use pointer arithmetic to
cycle through the memory address, and marshal the values back to you.

You should post the declaration of the function in unmanaged code, as I
am looking at your parameters, and they seem rather odd. For example, you
are using a StringBuilder for a parameter named HWND. Now, it may be that
this parameter is a string, and named HWND, but typically, I see that for
windows handles, not strings, which makes me think that there is something
much more amiss.

Hope this helps.
 
Nicholas:

Here's the DLL declaration:
DLLEXPORT float WINAPI GetXXX (HWND, long, LPARAM);

The reason I use StringBuilder as a parameter is that I usually pass
null in the first paramter and if I code it as int HWND it complains
about converting<null> to int.

Thanks for the help!

Regards,

Dan
 
Dan,

That's not what you should declare this as then.

Your declaration should be:

[DllImportAttribute("xx32_.DLL", CharSet=CharSet.Auto)]
extern static float GetXXX(
IntPtr hWnd,
int nWhat,
IntPtr lParam);

A long in C++ is a 32-bit integer, while in C#, it is a 64-bit integer.
This definitely screws up your call.

Also, you should use IntPtr, and pass IntPtr.Zero for the first
parameter.

Finally, you didn't answer what the third parameter is. An LPARAM is
just an IntPtr, but you don't specify if the array returned is created by
the function, or if it is the responsibility of the user to allocate it.
 

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

Back
Top