* 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
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.
On 27 September 2012 15:07, Federico.Balaguer <federico.balaguer@gmail.com> 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.
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 -- 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.
On 28 September 2012 14:41, Federico.Balaguer <federico.balaguer@gmail.com> 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.
participants (3)
-
Federico.Balaguer -
Igor Stasenko -
S Krish