FFI basics..

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

FFI basics..

S Krish

* How does FFI work for passing a char* argument that gets modified in the invoked module

char*   ctest ( char* test , char** test2)
{
     test = "Modify this argument";
     // loop and fill in data into test2 and return..
     return "something else";
}

  ctest: test
<cdecl: char* 'ctest' ( char* , long ) module: 'libctest'>


So invoking this with say ExternalAddress allocate: **,  gives us the values as modified by the module.. and be converted as required into ByteArray for the second
Reply | Threaded
Open this post in threaded view
|

Re: FFI basics..

Federico.Balaguer
This post was updated on .
I was looking for information in this area ( I am trying to call a simple function with a int* parameter)  

The part that I don't quite get is how I should invoke the method. I don't understand how should I use ExternalAddress

Thanks! Federico
Reply | Threaded
Open this post in threaded view
|

Re: FFI basics..

Federico.Balaguer
In reply to this post by S Krish
I was looking for information in this area and this part of your hint :

"So invoking this with say ExternalAddress allocate: **,  gives us the
values as modified by the module.. and be converted as required into
ByteArray for the second"


makes me scratch my head for a while now :-).

The part that I don't quite get is how should I use ExternalAddress (and
ExternalData). I have to make a call to a function that has a int* parameter

Thanks! Federico



--
View this message in context: http://forum.world.st/FFI-basics-tp4531126p4649258.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: FFI basics..

Igor Stasenko
On 27 September 2012 15:07, Federico.Balaguer
<[hidden email]> wrote:

> I was looking for information in this area and this part of your hint :
>
> "So invoking this with say ExternalAddress allocate: **,  gives us the
> values as modified by the module.. and be converted as required into
> ByteArray for the second"
>
>
> makes me scratch my head for a while now :-).
>
> The part that I don't quite get is how should I use ExternalAddress (and
> ExternalData). I have to make a call to a function that has a int* parameter
>
just allocate a buffer in external memory to big enough to hold the
type value (4 bytes for int32)
and pass it as argument to that function.
then you should be able to read it back.

In NativeBoost you can do a following:

intType := NBExternalTypeValue ofType: 'int'.
"this will create an anonymous class for object, holding a value of
type 'int' , so you actually don't need
to do this all the time, just once in initialization of your class/package"

intValue := intType new.   "this will create a new instance"


self foo: intValue

(where #foo  calls the function which expects int* argument)


intValue value  - to read the value.
invValue value: 5 - to write the value.


> Thanks! Federico
>
>
>
> --
> View this message in context: http://forum.world.st/FFI-basics-tp4531126p4649258.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>



--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: FFI basics..

Federico.Balaguer
Thanks Igor,

I finally got it working. I am putting the code here so I can easily find it next time I need to do this ;-)... and perhaps someone can point out a better way to do it with ffi.

BTW, NB looks very interesting, could it be possible to use it on 64bits? or as someone said about ffi, it could require a major rewrite?

cheers!

incrementIntegerPointer: integerValue
        "FFITest incrementIntegerPointer: 3"

        | pointer integer data |
        (pointer := ExternalAddress allocate: ExternalType long byteSize) signedLongAt: 1 put: integerValue.
        data := ExternalData fromHandle: pointer type: ExternalType long asPointerType.
        self integerAsPointer: data.
        ^ pointer signedLongAt: 1


integerAsPointer: integer
       
        <cdecl: void  'IntegerAsPointer' (long *) module:'ffitest.so'>
        ^self externalCallFailed
Reply | Threaded
Open this post in threaded view
|

Re: FFI basics..

Igor Stasenko
On 28 September 2012 14:41, Federico.Balaguer
<[hidden email]> wrote:
> Thanks Igor,
>
> I finally got it working. I am putting the code here so I can easily find it
> next time I need to do this ;-)... and perhaps someone can point out a
> better way to do it with ffi.
>
> BTW, NB looks very interesting, could it be possible to use it on 64bits? or
> as someone said about ffi, it could require a major rewrite?

for running NB FFI on 64 bits, first you need 64-bit VM.
making NB work on 64-bits will require writing (but not rewriting)
additional code, of course.

>
> cheers!
>
> incrementIntegerPointer: integerValue
>         "FFITest incrementIntegerPointer: 3"
>
>         | pointer integer data |
>         (pointer := ExternalAddress allocate: ExternalType long byteSize)
> signedLongAt: 1 put: integerValue.
>         data := ExternalData fromHandle: pointer type: ExternalType long
> asPointerType.
>         self integerAsPointer: data.
>         ^ pointer signedLongAt: 1
>
>
> integerAsPointer: integer
>
>         <cdecl: void  'IntegerAsPointer' (long *) module:'ffitest.so'>
>         ^self externalCallFailed
>
>
>
>
> --
> View this message in context: http://forum.world.st/FFI-basics-tp4531126p4649417.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>



--
Best regards,
Igor Stasenko.