[Q] How can I write down my FFI method for this C function? (Sorry if duplicated)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[Q] How can I write down my FFI method for this C function? (Sorry if duplicated)

Sungjin Chun
Hi,

The C function is like this;

BOOL ComputeVector (int startIdx, int endIdx, double *inputSeries, int
duration, int *outBeginIdx, int *outNBElement, double *outSeries);

My trial method is

apiComputeVectorWith: startIdx with: endIdx with: input duration:
duration with: outBeginIdx with: outNBElement out: out
   <cdecl: bool 'ComputeVector' (long long double* long long* long* double*)>

But with these input variable, I got error with "could not coerce arguments".

input := ((1 to: 100) collect: [ :i | i ]) asFloatArray.
startIdx := 0.
endIdx := input size - 1.
duration := 4.
outBeginIndx := IntegerArray new: 1.
outNBElement := IntegerArray new: 1.
out := FloatArray new: input size.
computer apiComputeVectorWith: startIdx with: endIdx with: input
duration: duration with: outBeginIdx with: outNBElement out: out.

Can anyone help me on this? Thank you in advance.
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: [Q] How can I write down my FFI method for this C function? (Sorry if duplicated)

Levente Uzonyi-2
On Fri, 4 Mar 2011, Sungjin Chun wrote:

> Hi,
>
> The C function is like this;
>
> BOOL ComputeVector (int startIdx, int endIdx, double *inputSeries, int
> duration, int *outBeginIdx, int *outNBElement, double *outSeries);
>
> My trial method is
>
> apiComputeVectorWith: startIdx with: endIdx with: input duration:
> duration with: outBeginIdx with: outNBElement out: out
>   <cdecl: bool 'ComputeVector' (long long double* long long* long* double*)>
>
> But with these input variable, I got error with "could not coerce arguments".
>
> input := ((1 to: 100) collect: [ :i | i ]) asFloatArray.
> startIdx := 0.
> endIdx := input size - 1.
> duration := 4.
> outBeginIndx := IntegerArray new: 1.
> outNBElement := IntegerArray new: 1.
> out := FloatArray new: input size.
> computer apiComputeVectorWith: startIdx with: endIdx with: input
> duration: duration with: outBeginIdx with: outNBElement out: out.
>
> Can anyone help me on this? Thank you in advance.

The cause of the error is that FloatArray is an array of 32-bit floats
(unlike Float which is a 64-bit floating point number aka double).
Your method expects double*. AFAIK there's no Smalltalk type that matches
double*, so you have to coerce the arguments yourself.
Here's how you can do it (I didn't try it, so it may not work):

"We will pass WordArrays, since Floats consist of two words, which makes
coercion easy."

apiComputeVectorWith: startIdx with: endIdx with: input duration:
duration with: outBeginIdx with: outNBElement out: out
    <cdecl: bool 'ComputeVector' (long long long* long long* long*
long*)>

input := WordArray new: 200.
1 to: 100 do: [ :i |
  | float |
  float := i asFloat.
  input at: 2 * i - 1 put: (float at: 1).
  input at: 2 * i put: (float at: 2) ]
startIdx := 0.
endIdx := input size - 1.
duration := 4.
outBeginIndx := IntegerArray new: 1.
outNBElement := IntegerArray new: 1.
out := WordArray new: input size.
computer apiComputeVectorWith: startIdx with: endIdx with: input duration: duration with: outBeginIdx with: outNBElement out: out.
out := out pairsCollect: [ :word1 :word2 |
  (Float new: 2)
  at: 1 put: word1;
  at: 2 put: word2;
  yourself ]


Levente

> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: [Q] How can I write down my FFI method for this C function? (Sorry if duplicated)

Sungjin Chun
Ah, I got it. Then, I can use your suggestion or modify/fix the function to use float instead of double. :-)

Thank you very much.

On Mar 5, 2011, at 1:52, Levente Uzonyi <[hidden email]> wrote:

> On Fri, 4 Mar 2011, Sungjin Chun wrote:
>
>> Hi,
>>
>> The C function is like this;
>>
>> BOOL ComputeVector (int startIdx, int endIdx, double *inputSeries, int
>> duration, int *outBeginIdx, int *outNBElement, double *outSeries);
>>
>> My trial method is
>>
>> apiComputeVectorWith: startIdx with: endIdx with: input duration:
>> duration with: outBeginIdx with: outNBElement out: out
>>  <cdecl: bool 'ComputeVector' (long long double* long long* long* double*)>
>>
>> But with these input variable, I got error with "could not coerce arguments".
>>
>> input := ((1 to: 100) collect: [ :i | i ]) asFloatArray.
>> startIdx := 0.
>> endIdx := input size - 1.
>> duration := 4.
>> outBeginIndx := IntegerArray new: 1.
>> outNBElement := IntegerArray new: 1.
>> out := FloatArray new: input size.
>> computer apiComputeVectorWith: startIdx with: endIdx with: input
>> duration: duration with: outBeginIdx with: outNBElement out: out.
>>
>> Can anyone help me on this? Thank you in advance.
>
> The cause of the error is that FloatArray is an array of 32-bit floats (unlike Float which is a 64-bit floating point number aka double).
> Your method expects double*. AFAIK there's no Smalltalk type that matches double*, so you have to coerce the arguments yourself.
> Here's how you can do it (I didn't try it, so it may not work):
>
> "We will pass WordArrays, since Floats consist of two words, which makes coercion easy."
>
> apiComputeVectorWith: startIdx with: endIdx with: input duration:
> duration with: outBeginIdx with: outNBElement out: out
>   <cdecl: bool 'ComputeVector' (long long long* long long* long* long*)>
>
> input := WordArray new: 200.
> 1 to: 100 do: [ :i |
>    | float |
>    float := i asFloat.
>    input at: 2 * i - 1 put: (float at: 1).
>    input at: 2 * i put: (float at: 2) ]
> startIdx := 0.
> endIdx := input size - 1.
> duration := 4.
> outBeginIndx := IntegerArray new: 1.
> outNBElement := IntegerArray new: 1.
> out := WordArray new: input size.
> computer apiComputeVectorWith: startIdx with: endIdx with: input duration: duration with: outBeginIdx with: outNBElement out: out.
> out := out pairsCollect: [ :word1 :word2 |
>    (Float new: 2)
>        at: 1 put: word1;
>        at: 2 put: word2;
>        yourself ]
>
>
> Levente
>
>> _______________________________________________
>> Beginners mailing list
>> [hidden email]
>> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners