pinvoke double[] to Intptr , passing double as IntPtr ??

S

Sagaert Johan

Hi

I am struggling with pinvoke

I have dll a function that is declared as :
sf_command (IntPtr sndfile,int command, IntPtr data, int datasize);

i need to pass a pointer to a double in the data parameter, i now did :

IntPtr mem = Marshal.AllocHGlobal(sizeof(double));

sf_command (sndfile,command, mem, sizeof(double));

then i did

byte[] ba=new byte[sizeof (Double)];

ba[0]=Marshal.ReadByte(mem,0);
ba[1]=Marshal.ReadByte(mem,1);
ba[2]=Marshal.ReadByte(mem,2);
ba[3]=Marshal.ReadByte(mem,3);
ba[4] = Marshal.ReadByte(mem, 4);
ba[5] = Marshal.ReadByte(mem, 5);
ba[6] = Marshal.ReadByte(mem, 6);
ba[7] = Marshal.ReadByte(mem, 7);

max_val = BitConverter.ToDouble(ba,0);

Marshal.FreeHGlobal(mem);


this works ,but i think there should be a shorter way ??

second question :
How do i pass an array doubles to my function ?


Johan
 
B

Ben Voigt [C++ MVP]

Sagaert said:
Hi

I am struggling with pinvoke

I have dll a function that is declared as :
sf_command (IntPtr sndfile,int command, IntPtr data, int datasize);

i need to pass a pointer to a double in the data parameter, i now did
:
IntPtr mem = Marshal.AllocHGlobal(sizeof(double));

sf_command (sndfile,command, mem, sizeof(double));

then i did

byte[] ba=new byte[sizeof (Double)];

ba[0]=Marshal.ReadByte(mem,0);
ba[1]=Marshal.ReadByte(mem,1);
ba[2]=Marshal.ReadByte(mem,2);
ba[3]=Marshal.ReadByte(mem,3);
ba[4] = Marshal.ReadByte(mem, 4);
ba[5] = Marshal.ReadByte(mem, 5);
ba[6] = Marshal.ReadByte(mem, 6);
ba[7] = Marshal.ReadByte(mem, 7);

max_val = BitConverter.ToDouble(ba,0);

Marshal.FreeHGlobal(mem);


this works ,but i think there should be a shorter way ??

second question :
How do i pass an array doubles to my function ?

Did you try the obvious solution of using either "double[]" or "ref double"
as the type of the argument in the DllImport?
 
P

Pavel Minaev

Hi

I am struggling with pinvoke

I  have dll a function that is declared as :
sf_command (IntPtr sndfile,int command, IntPtr data, int datasize);

i need to pass a pointer to a double in the data parameter, i now did :

IntPtr mem = Marshal.AllocHGlobal(sizeof(double));

sf_command (sndfile,command, mem, sizeof(double));

then  i did

byte[] ba=new byte[sizeof (Double)];

ba[0]=Marshal.ReadByte(mem,0);
ba[1]=Marshal.ReadByte(mem,1);
ba[2]=Marshal.ReadByte(mem,2);
ba[3]=Marshal.ReadByte(mem,3);
ba[4] = Marshal.ReadByte(mem, 4);
ba[5] = Marshal.ReadByte(mem, 5);
ba[6] = Marshal.ReadByte(mem, 6);
ba[7] = Marshal.ReadByte(mem, 7);

max_val = BitConverter.ToDouble(ba,0);

Marshal.FreeHGlobal(mem);

this works ,but i think there should be a shorter way ??

Yes. For one thing, you can just declare the parameter as double[] in
the P/Invoke declaration for your function (or "ref double[]" if the
function is going to write some data into that array). For another,
you can use pointers:

double* p = (double*)mem;
Console.WriteLine(*p);

of course, this necessitates the use of "/unsafe", but there's nothing
inherently wrong about it. Pointers exist in C# for a reason, so don't
be afraid to use them for interop.
 
S

Sagaert Johan

Hi
casting double does not work (IntPtr) double

Changing my pinvoke declaration from IntPtr to ref double is no option,
since in other case i need to pass pointer to other data type too.

I did find this is a cleaner alternative (since a double is in fact a
structure type )

IntPtr mem = Marshal.AllocHGlobal(sizeof(double));

int err = sf_command(Hsoundfile, SFCommand.SFC_CALC_NORM_SIGNAL_MAX, mem,
sizeof(double)); CheckError(err);

double max_val = (double)Marshal.PtrToStructure(mem, typeof(System.Double));
Marshal.FreeHGlobal(mem); return max_val;



Ben Voigt said:
Sagaert said:
Hi

I am struggling with pinvoke

I have dll a function that is declared as :
sf_command (IntPtr sndfile,int command, IntPtr data, int datasize);

i need to pass a pointer to a double in the data parameter, i now did
:
IntPtr mem = Marshal.AllocHGlobal(sizeof(double));

sf_command (sndfile,command, mem, sizeof(double));

then i did

byte[] ba=new byte[sizeof (Double)];

ba[0]=Marshal.ReadByte(mem,0);
ba[1]=Marshal.ReadByte(mem,1);
ba[2]=Marshal.ReadByte(mem,2);
ba[3]=Marshal.ReadByte(mem,3);
ba[4] = Marshal.ReadByte(mem, 4);
ba[5] = Marshal.ReadByte(mem, 5);
ba[6] = Marshal.ReadByte(mem, 6);
ba[7] = Marshal.ReadByte(mem, 7);

max_val = BitConverter.ToDouble(ba,0);

Marshal.FreeHGlobal(mem);


this works ,but i think there should be a shorter way ??

second question :
How do i pass an array doubles to my function ?

Did you try the obvious solution of using either "double[]" or "ref
double" as the type of the argument in the DllImport?
 
B

Ben Voigt [C++ MVP]

Sagaert Johan said:
Hi
casting double does not work (IntPtr) double

Changing my pinvoke declaration from IntPtr to ref double is no option,
since in other case i need to pass pointer to other data type too.

You can have multiple p/invoke declarations for the same function with
different argument lists, just like any overloaded function.
 

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