Hi, but this will not work either (I just realised). This is complicated matter and confuses many (even me, some times :P). I will try explain.
Technically, when you do array := (FFIExternalArray externalNewType: 'void*' size: parameters size) autoRelease. you are declaring (in C) (void*)[] array; which (in C) is synonym of: void** which means that as soon as you declare your array, you already have a void** then, your call has to be: ... self prim_initEmbeddedRargc: parameters size argv: externalArray. with call of: self ffiCall: #(int Rf_initEmbeddedR(int argc, FFIExternalArrayOfStrings argv)) (is better to declare a subclass of FFIExternalArray to be clear about your purpose). or the other way. Since UFFI cannot determine if an ExternalAddress is a pointer (void*) or a pointer to a pointer (void**), because for C, at the end, they are exactly the same, you need to declare as this: self prim_initEmbeddedRargc: parameters size argv: externalArray getHandle. with call of: self ffiCall: #(int Rf_initEmbeddedR(int argc, void *argv)) remarks: 1) you need to declare it as “void*" because UFFI will box any arity > [object natural arity], which in arrays is 1 (then, if you pass ** it will box it into a –wrong– void***… bad. 2) in this case, since you are passing a handle (a pointer), you do not need/want to subclass FFIExternalArray. Finally, a third way (not tested), is just doing: self prim_initEmbeddedRargc: parameters size argv: externalArray getHandle. with call of: self ffiCall: #(int Rf_initEmbeddedR(int argc, oop argv)) in this case, it will pass the handle (pointer) “as is”, without transformation. This should work but I never tested it. Maybe in terms of clarity, last form is better… I don’t know :P confusing? yes but it is because is very hard to determine/parse/interpret pointer arities and keep the calls efficient, in a moment we need to put a limit in automatic translations. Esteban > On 04 Jun 2016, at 10:10, Esteban Lorenzano <esteba...@gmail.com> wrote: > > Hi, > > sorry late response, I just missed this mails. > > but… I do not have much to say… what you did should work. > Except (I think I’d need to look at your code closer) you need to change the > argument of argv to FFIExternalArray*, or you need to pass the handle to the > function. Something like this: > > > | externalArray parameters | > > parameters := #('R' '--no-save' 'silent'). > externalArray := (FFIExternalArray externalNewType: 'void*' size: parameters > size) autoRelease. > parameters withIndexDo: [ :string :index | > externalArray at: index put: (ExternalAddress fromString: string) > autoRelease ]. > self prim_initEmbeddedRargc: parameters size argv: externalArray getHandle > > (with same primitive call) > > or without the #getHandle message and a primitive call: > > self ffiCall: #(int Rf_initEmbeddedR(int argc, FFIExternalArray* argv)) > > AFAIK, that should work… if not I’d need to take a better look, because is > maybe a bug :P > > Esteban > >> On 03 Jun 2016, at 18:50, Blondeau Vincent <vincent.blond...@worldline.com> >> wrote: >> >> Hello, >> >> So, we tried with Thibault Raffaillac and we succeed to have this kind of >> code: >> >> >> | externalArray | >> parameters := #('R' '--no-save' 'silent'). >> [ externalArray := FFIExternalArray externalNewType: 'void*' size: >> parameters size. >> parameters >> withIndexDo: [ :string :index | externalArray at: index put: >> (ExternalAddress fromString: string) ]. >> self prim_initEmbeddedRargc: parameters size argv: externalArray ] >> ensure: [ externalArray >> ifNotNil: [ externalArray do: [ :item | item >> ifNotNil: [ :e | e free ] ]. >> externalArray free ] ] >> >> with a primitive call: >> self ffiCall: #(int Rf_initEmbeddedR(int argc, char ** argv)) >> >> However, it still doesn't work because the VM is crashing during the call to >> the primitive. >> >> Does the translation from the Nativeboost version is accurate? >> >> Thanks in advance for your help, >> >> Vincent >> >>> -----Message d'origine----- >>> De : Pharo-users [mailto:pharo-users-boun...@lists.pharo.org] De la part de >>> Julien Delplanque >>> Envoyé : mercredi 1 juin 2016 18:49 >>> À : pharo-users@lists.pharo.org >>> Objet : Re: [Pharo-users] [UFFI] Call a function where argument type is >>> char ** >>> (argv) >>> >>> Hello, >>> >>> I asked a simililar question some days ago, maybe this [1] can help. >>> >>> Regards, >>> >>> Julien >>> >>> Links: >>> >>> [1]: >>> http://forum.world.st/Unified-FFI-pointer-of-String-as-function-parameter- >>> td4898066.html >>> >>> >>> On 31/05/16 16:28, Blondeau Vincent wrote: >>>> TL;DR: How to pass as argument an array of Strings (char **) with Unified- >>> FFI? >>>> >>>> Vincent >>>> >>>> De : Blondeau Vincent >>>> Envoyé : mercredi 25 mai 2016 13:58 >>>> À : Pharo Development List >>>> Objet : [UFFI] Call a function where argument type is char ** (argv) >>>> >>>> Hello, >>>> >>>> I have written a R bridge in Pharo and I would like to migrate it from >>> NativeBoost to UFFI. >>>> Most of the changes are easy to do but I am stuck to a double pointer >>> problem. >>>> I have to call the function: int Rf_initEmbeddedR(int argc, char ** argv). >>>> I >>> know how to give the int but the char ** is a problem. It is an array of >>> Strings. >>>> >>>> With NB, I managed to have this (working) code: >>>> "This is 32bit... too bad..." >>>> strings := OrderedCollection new. >>>> par := NativeBoost allocate: 4 * params size. >>>> params >>>> keysAndValuesDo: [ :i :each | >>>> | str | >>>> str := each >>>> asNBExternalString. >>>> strings add: str. >>>> par nbUInt32AtOffset: (i - >>>> 1) * 4 put: str value ]. >>>> self prim_initEmbeddedRargc: params size argv: par ] >>>> ensure: [ >>>> "Free the memory we >>>> allocated" >>>> par ifNotNil: [ par free ]. >>>> strings ifNotNil: [ >>>> strings do: [ :each | each free ] ] ] >>>> >>>> With a primitive call: >>>> Self nbCall: #(int Rf_initEmbeddedR(int argc, char *argv)) >>>> >>>> Do I still need to create my own array of strings or FFI creates it for me? >>> How? >>>> >>>> Thanks in advance for your answers, >>>> >>>> Vincent >>>> >>>> >>>> >>> !!!*************************************************************** >>> **** >>>> ****************** "Ce message et les pièces jointes sont >>>> confidentiels et réservés à l'usage exclusif de ses destinataires. Il peut >>> également être protégé par le secret professionnel. Si vous recevez ce >>> message par erreur, merci d'en avertir immédiatement l'expéditeur et de le >>> détruire. L'intégrité du message ne pouvant être assurée sur Internet, la >>> responsabilité de Worldline ne pourra être recherchée quant au contenu de >>> ce message. Bien que les meilleurs efforts soient faits pour maintenir cette >>> transmission exempte de tout virus, l'expéditeur ne donne aucune garantie à >>> cet égard et sa responsabilité ne saurait être recherchée pour tout dommage >>> résultant d'un virus transmis. >>>> >>>> This e-mail and the documents attached are confidential and intended >>> solely for the addressee; it may also be privileged. If you receive this >>> e-mail in >>> error, please notify the sender immediately and destroy it. As its integrity >>> cannot be secured on the Internet, the Worldline liability cannot be >>> triggered >>> for the message content. Although the sender endeavours to maintain a >>> computer virus-free network, the sender does not warrant that this >>> transmission is virus-free and will not be liable for any damages resulting >>> from any virus transmitted.!!!" >>>> >>> >> >> >> !!!************************************************************************************* >> "Ce message et les pièces jointes sont confidentiels et réservés à l'usage >> exclusif de ses destinataires. Il peut également être protégé par le secret >> professionnel. Si vous recevez ce message par erreur, merci d'en avertir >> immédiatement l'expéditeur et de le détruire. L'intégrité du message ne >> pouvant être assurée sur Internet, la responsabilité de Worldline ne pourra >> être recherchée quant au contenu de ce message. Bien que les meilleurs >> efforts soient faits pour maintenir cette transmission exempte de tout >> virus, l'expéditeur ne donne aucune garantie à cet égard et sa >> responsabilité ne saurait être recherchée pour tout dommage résultant d'un >> virus transmis. >> >> This e-mail and the documents attached are confidential and intended solely >> for the addressee; it may also be privileged. If you receive this e-mail in >> error, please notify the sender immediately and destroy it. As its integrity >> cannot be secured on the Internet, the Worldline liability cannot be >> triggered for the message content. Although the sender endeavours to >> maintain a computer virus-free network, the sender does not warrant that >> this transmission is virus-free and will not be liable for any damages >> resulting from any virus transmitted.!!!" >> >