Connecting Tech Pros Worldwide Forums | Help | Site Map

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

Sagaert Johan
Guest
 
Posts: n/a
#1: Nov 20 '08
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



Ben Voigt [C++ MVP]
Guest
 
Posts: n/a
#2: Nov 20 '08

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


Sagaert Johan wrote:
Quote:
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?
Quote:
>
>
Johan

Pavel Minaev
Guest
 
Posts: n/a
#3: Nov 21 '08

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


On Nov 20, 11:25*pm, "Sagaert Johan" <REMOVEsagaer...@hotmail.com>
wrote:
Quote:
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.

Quote:
second question :
How do i pass an array doubles to my function ?
>
Johan
Sagaert Johan
Guest
 
Posts: n/a
#4: Nov 21 '08

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


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 [C++ MVP]" <rbv@nospam.nospamwrote in message
news:u4eSVu1SJHA.5080@TK2MSFTNGP03.phx.gbl...
Quote:
Sagaert Johan wrote:
Quote:
>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?
>
Quote:
>>
>>
>Johan
>
>

Ben Voigt [C++ MVP]
Guest
 
Posts: n/a
#5: Nov 21 '08

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




"Sagaert Johan" <REMOVEsagaert_j@hotmail.comwrote in message
news:Oy2$QpBTJHA.5056@TK2MSFTNGP04.phx.gbl...
Quote:
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.


Closed Thread