[squeak-dev] FFI problem: "could not coerce arguments"

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

[squeak-dev] FFI problem: "could not coerce arguments"

Mariano Martinez Peck
sorry...now it goes in English...

I have a problem trying to invoke a function through FFI. I have bee using FFI y some functions with no problem but now I have "could not coerce arguments". This is the first time I have a void* parameter, so I believe that could be the problem.

The function definition is:
int odbx_set_option(
odbx_t* handle,
unsigned int option,
void* value )


Here is an example that shows how to use it in C:

option = ODBX_TLS_ALWAYS;
if( ( err = odbx_set_option( handle, ODBX_OPT_TLS, (void*) &option ) ) < 0 )
{
fprintf( stderr, "odbx_set_option(): %s\n", odbx_error( handle, err ) );
odbx_finish( handle );
return err;
}


This is my method that map that function with FFI:

apiSetOption: handle option: anOption value: aValue
    "int odbx_unbind(odbx_t*)"
    <cdecl: long 'odbx_set_option' (ulong ulong void*) module: 'opendbx' >
    ^self externalCallFailed
   

I proobed void*, void, ulong y ulong* but I had that error in all cases.

Here is how my method is used:

err := OpenDBX apiSetOption: self option:32  value:1.

So, can someone help me?

thanks,

mariano



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] FFI problem: "could not coerce arguments"

Bert Freudenberg

On 26.05.2008, at 15:21, Mariano Martinez Peck wrote:

> "could not coerce arguments"
> int odbx_set_option(
>     odbx_t* handle,
>     unsigned int option,
>     void* value )
> apiSetOption: handle option: anOption value: aValue
>     "int odbx_unbind(odbx_t*)"
>     <cdecl: long 'odbx_set_option' (ulong ulong void*) module:  
> 'opendbx' >
>     ^self externalCallFailed
>
> err := OpenDBX apiSetOption: self option:32  value:1.


The first argument appears to be a pointer to a handle object. You  
probably should not declare that as ulong if you then pass  
"self" (which I assume is a ExternalStructure subclass). But that  
depends on how you acquire the handle, and how you represent it in the  
image.

The argument to void* should be a ByteArray or WordArray, methinks,  
I'd try "WordArray with: 1" if you want to pass a pointer to the  
Integer 1.

- Bert -



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] FFI problem: "could not coerce arguments"

Mariano Martinez Peck


On Mon, May 26, 2008 at 10:36 AM, Bert Freudenberg <[hidden email]> wrote:

On 26.05.2008, at 15:21, Mariano Martinez Peck wrote:

"could not coerce arguments"

int odbx_set_option(
   odbx_t* handle,
   unsigned int option,
   void* value )
apiSetOption: handle option: anOption value: aValue
   "int odbx_unbind(odbx_t*)"
   <cdecl: long 'odbx_set_option' (ulong ulong void*) module: 'opendbx' >
   ^self externalCallFailed

err := OpenDBX apiSetOption: self option:32  value:1.


The first argument appears to be a pointer to a handle object. You probably should not declare that as ulong if you then pass "self" (which I assume is a ExternalStructure subclass). But that depends on how you acquire the handle, and how you represent it in the image.

Yes you are right, sorry. It was not self, but a attribute called handle. My mistake.
 

The argument to void* should be a ByteArray or WordArray, methinks, I'd try "WordArray with: 1" if you want to pass a pointer to the Integer 1.

- Bert -

Sounds interesting. I will test it and then I tell you.

Thanks,

Mariano

 



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] FFI problem: "could not coerce arguments"

Mariano Martinez Peck


On Mon, May 26, 2008 at 10:44 AM, Mariano Martinez Peck <[hidden email]> wrote:


On Mon, May 26, 2008 at 10:36 AM, Bert Freudenberg <[hidden email]> wrote:

On 26.05.2008, at 15:21, Mariano Martinez Peck wrote:

"could not coerce arguments"

int odbx_set_option(
   odbx_t* handle,
   unsigned int option,
   void* value )
apiSetOption: handle option: anOption value: aValue
   "int odbx_unbind(odbx_t*)"
   <cdecl: long 'odbx_set_option' (ulong ulong void*) module: 'opendbx' >
   ^self externalCallFailed

err := OpenDBX apiSetOption: self option:32  value:1.


The first argument appears to be a pointer to a handle object. You probably should not declare that as ulong if you then pass "self" (which I assume is a ExternalStructure subclass). But that depends on how you acquire the handle, and how you represent it in the image.

Yes you are right, sorry. It was not self, but a attribute called handle. My mistake.
 

The argument to void* should be a ByteArray or WordArray, methinks, I'd try "WordArray with: 1" if you want to pass a pointer to the Integer 1.

- Bert -

Sounds interesting. I will test it and then I tell you.



Bert: I test this using WordArray and I work perfect in all the cases the value was a number. But the type in the function definition is void*. So, now, I need to send not only a 1 or 0, but a String. In this case, I cannot do WordArray with: 'aStringValue'  neither ByteArray with: 'aStringValue' . What can I do in this case? Do you have any idea?

I mean, I need to use the same parametrer void*, sending it a number or a string.

many thanks,

mariano
 
Thanks,

Mariano

 




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] FFI problem: "could not coerce arguments"

Bert Freudenberg
Am 18.08.2008 um 20:44 schrieb Mariano Martinez Peck:

>
>
> On Mon, May 26, 2008 at 10:44 AM, Mariano Martinez Peck <[hidden email]
> > wrote:
>
>
> On Mon, May 26, 2008 at 10:36 AM, Bert Freudenberg <[hidden email]
> > wrote:
>
> On 26.05.2008, at 15:21, Mariano Martinez Peck wrote:
>
> "could not coerce arguments"
>
> int odbx_set_option(
>    odbx_t* handle,
>    unsigned int option,
>    void* value )
> apiSetOption: handle option: anOption value: aValue
>    "int odbx_unbind(odbx_t*)"
>    <cdecl: long 'odbx_set_option' (ulong ulong void*) module:  
> 'opendbx' >
>    ^self externalCallFailed
>
> err := OpenDBX apiSetOption: self option:32  value:1.
>
>
> The first argument appears to be a pointer to a handle object. You  
> probably should not declare that as ulong if you then pass  
> "self" (which I assume is a ExternalStructure subclass). But that  
> depends on how you acquire the handle, and how you represent it in  
> the image.
>
> Yes you are right, sorry. It was not self, but a attribute called  
> handle. My mistake.
>
>
> The argument to void* should be a ByteArray or WordArray, methinks,  
> I'd try "WordArray with: 1" if you want to pass a pointer to the  
> Integer 1.
>
> - Bert -
>
> Sounds interesting. I will test it and then I tell you.
>
>
>
> Bert: I test this using WordArray and I work perfect in all the  
> cases the value was a number. But the type in the function  
> definition is void*. So, now, I need to send not only a 1 or 0, but  
> a String. In this case, I cannot do WordArray with: 'aStringValue'  
> neither ByteArray with: 'aStringValue' . What can I do in this case?  
> Do you have any idea?
>
> I mean, I need to use the same parametrer void*, sending it a number  
> or a string.


Declare the method again like

apiSetOption: handle option: anOption string: aString
    <cdecl: long 'odbx_set_option' (ulong ulong char*) module:  
'opendbx' >
    ^self externalCallFailed

and use that by simply passing a String (don't even bother to convert  
to ByteArray [but watch out for the terminating 0]).

- Bert -


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] FFI problem: "could not coerce arguments"

Bert Freudenberg

Am 18.08.2008 um 21:29 schrieb Bert Freudenberg:

> Am 18.08.2008 um 20:44 schrieb Mariano Martinez Peck:
>
>>
>>
>> On Mon, May 26, 2008 at 10:44 AM, Mariano Martinez Peck <[hidden email]
>> > wrote:
>>
>>
>> On Mon, May 26, 2008 at 10:36 AM, Bert Freudenberg <[hidden email]
>> > wrote:
>>
>> On 26.05.2008, at 15:21, Mariano Martinez Peck wrote:
>>
>> "could not coerce arguments"
>>
>> int odbx_set_option(
>>   odbx_t* handle,
>>   unsigned int option,
>>   void* value )
>> apiSetOption: handle option: anOption value: aValue
>>   "int odbx_unbind(odbx_t*)"
>>   <cdecl: long 'odbx_set_option' (ulong ulong void*) module:  
>> 'opendbx' >
>>   ^self externalCallFailed
>>
>> err := OpenDBX apiSetOption: self option:32  value:1.
>>
>>
>> The first argument appears to be a pointer to a handle object. You  
>> probably should not declare that as ulong if you then pass  
>> "self" (which I assume is a ExternalStructure subclass). But that  
>> depends on how you acquire the handle, and how you represent it in  
>> the image.
>>
>> Yes you are right, sorry. It was not self, but a attribute called  
>> handle. My mistake.
>>
>>
>> The argument to void* should be a ByteArray or WordArray, methinks,  
>> I'd try "WordArray with: 1" if you want to pass a pointer to the  
>> Integer 1.
>>
>> - Bert -
>>
>> Sounds interesting. I will test it and then I tell you.
>>
>>
>>
>> Bert: I test this using WordArray and I work perfect in all the  
>> cases the value was a number. But the type in the function  
>> definition is void*. So, now, I need to send not only a 1 or 0, but  
>> a String. In this case, I cannot do WordArray with: 'aStringValue'  
>> neither ByteArray with: 'aStringValue' . What can I do in this  
>> case? Do you have any idea?
>>
>> I mean, I need to use the same parametrer void*, sending it a  
>> number or a string.
>
>
> Declare the method again like
>
> apiSetOption: handle option: anOption string: aString
>   <cdecl: long 'odbx_set_option' (ulong ulong char*) module:  
> 'opendbx' >
>   ^self externalCallFailed
>
> and use that by simply passing a String (don't even bother to  
> convert to ByteArray [but watch out for the terminating 0]).
>
> - Bert -



... that is, unless this works with the original method (I'm not sure):

self apiSetOption: handle option: bla value: 'aStringValue' asByteArray.


- Bert -



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] FFI problem: "could not coerce arguments"

Mariano Martinez Peck
Yeah!  Bert:

 It works perfectly if I use char* and

self apiSetOption: handle option: bla value: 'aStringValue'

If I use void* and

self apiSetOption: handle option: bla value: 'aStringValue' asByteArray

it seems it doesn't arrives well to the library.

many thanks,

mariano

On Mon, Aug 18, 2008 at 4:33 PM, Bert Freudenberg <[hidden email]> wrote:

Am 18.08.2008 um 21:29 schrieb Bert Freudenberg:


Am 18.08.2008 um 20:44 schrieb Mariano Martinez Peck:



On Mon, May 26, 2008 at 10:44 AM, Mariano Martinez Peck <[hidden email]> wrote:


On Mon, May 26, 2008 at 10:36 AM, Bert Freudenberg <[hidden email]> wrote:

On 26.05.2008, at 15:21, Mariano Martinez Peck wrote:

"could not coerce arguments"

int odbx_set_option(
 odbx_t* handle,
 unsigned int option,
 void* value )
apiSetOption: handle option: anOption value: aValue
 "int odbx_unbind(odbx_t*)"
 <cdecl: long 'odbx_set_option' (ulong ulong void*) module: 'opendbx' >
 ^self externalCallFailed

err := OpenDBX apiSetOption: self option:32  value:1.


The first argument appears to be a pointer to a handle object. You probably should not declare that as ulong if you then pass "self" (which I assume is a ExternalStructure subclass). But that depends on how you acquire the handle, and how you represent it in the image.

Yes you are right, sorry. It was not self, but a attribute called handle. My mistake.


The argument to void* should be a ByteArray or WordArray, methinks, I'd try "WordArray with: 1" if you want to pass a pointer to the Integer 1.

- Bert -

Sounds interesting. I will test it and then I tell you.



Bert: I test this using WordArray and I work perfect in all the cases the value was a number. But the type in the function definition is void*. So, now, I need to send not only a 1 or 0, but a String. In this case, I cannot do WordArray with: 'aStringValue'  neither ByteArray with: 'aStringValue' . What can I do in this case? Do you have any idea?

I mean, I need to use the same parametrer void*, sending it a number or a string.


Declare the method again like

apiSetOption: handle option: anOption string: aString
 <cdecl: long 'odbx_set_option' (ulong ulong char*) module: 'opendbx' >
 ^self externalCallFailed

and use that by simply passing a String (don't even bother to convert to ByteArray [but watch out for the terminating 0]).

- Bert -



... that is, unless this works with the original method (I'm not sure):

self apiSetOption: handle option: bla value: 'aStringValue' asByteArray.


- Bert -






Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] FFI problem: "could not coerce arguments"

Bert Freudenberg

Am 19.08.2008 um 17:06 schrieb Mariano Martinez Peck:

> Yeah!  Bert:
>
>  It works perfectly if I use char* and
>
> self apiSetOption: handle option: bla value: 'aStringValue'


Great. In that case I'd simply keep those two methods  
apiSetOption:option:value: and apiSetOption:option:string:.

- Bert -



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] FFI problem: "could not coerce arguments"

Mariano Martinez Peck
Yes, that's a good idea!

thanks again,

Mariano

On Tue, Aug 19, 2008 at 12:15 PM, Bert Freudenberg <[hidden email]> wrote:

Am 19.08.2008 um 17:06 schrieb Mariano Martinez Peck:


Yeah!  Bert:

 It works perfectly if I use char* and

self apiSetOption: handle option: bla value: 'aStringValue'


Great. In that case I'd simply keep those two methods apiSetOption:option:value: and apiSetOption:option:string:.

- Bert -