Hello Igor, Thanks for your answer.
I implemented something like that for the printf function: Basically, it generates a method with matching arguments and executes it. *printf:* stringFormat *args:* tab > > | argNumber functionArgs functionPrototype methodCorpse methodSelector > argsArray | > > ((tab size % 2) = 0) ifFalse: [ > Transcript show: 'error'. > ^self. > ]. > > argNumber := 0. > functionPrototype := 'printf: stringFormat'. > functionArgs := ''. > methodCorpse := ''. > argsArray := (Array new: (tab size / 2) + 1). > argsArray at: 1 put: stringFormat. > > 1 to: tab size by: 2 do: [ :i | > functionPrototype := functionPrototype, ' arg', argNumber > asString, ': ', (tab at: i) asString, argNumber asString. > functionArgs := functionArgs, ' ', (tab at: i) asString, ' ', (tab > at: i) asString, argNumber asString, ','. > argsArray at: argNumber + 2 put: (tab at: i + 1). > argNumber := argNumber + 1. > ]. > functionArgs := functionArgs allButLast. > > methodCorpse := functionPrototype, Character cr asString, ' > <primitive: #primitiveNativeCall module: #NativeBoostPlugin>', Character cr > asString, Character cr asString, ' ^self nbCall: #( void printf ( String > stringFormat,', functionArgs asString, ' ) )', Character cr asString, ' > module: NativeBoost CLibrary'. > > methodSelector := self class compile: methodCorpse. > > self perform: methodSelector withArguments: argsArray. > Then you can call it like that : MyClass printf: 'Test of printf. String: %s, Int : %d, Long: %ld, Char: %c, Double: %lf' args: { 'String'. 'This is a string'. 'int'. 100. 'long'. 10000000. 'char'. 89. 'double'. 3.14159 }. I also tried it for some other variadic functions and, on my computer (I am running archlinux), it seemed to work for every type of argument except "float". It works fine for "double" though. For "char" you need to pass the integer ASCII value directly for it to work. I tried with "Character value: xxx" but it didn't work. I know that this is very hackish and very bad, and I am aware it has some drawbacks. Moreover I am not even sure it will work everytime. But for now it seems to work ... 2015-07-13 19:24 GMT+02:00 Igor Stasenko <siguc...@gmail.com>: > > > On 10 July 2015 at 10:18, Matthieu Lacaton <matthieu.laca...@gmail.com> > wrote: > >> Hello, >> >> Is it possible with NativeBoost to create a binding for a variadic >> function ? >> >> I've seen the printf example in NBCPrinter but this implementation is >> kind of cheating since it always pass just a %s as format and one already >> formatted string to the C function. >> >> I've written a simple variadic function which adds every integer it >> receives as argument (first argument is for the number of following >> arguments) : >> >> int add(int number,...); >> >> In Pharo I've tried something like this : >> >> *add: *number *arg1: *first *arg2: *second >>> <primitive: #primitiveNativeCall module: #NativeBoostPlugin> >>> >>> ^ self nbCall: #( int add (int number, int first, int second)) >>> module: 'libMyLib.so' >>> >> >> and it works fine with two arguments. >> >> Basically, doing so, I would need one method per number of arguments so >> it's not very cool. >> >> I thought that maybe I could pass an array as argument to my Pharo method >> but I didn't really find a way to figure out how to define the nbCall >> without having a "Generic failure". >> >> *add: *number *args: *anArray >>> <primitive: #primitiveNativeCall module: #NativeBoostPlugin> >>> >>> ^ self nbCall: #( int add (int number, ??? anArray)) >>> module: 'libMyLib.so' >>> >> >> Do you have an idea ? >> >> > In short, there's no marshaller for converting an array of items, to same > number of things on stack. That could solve the problem with your example: > passing array of objects of *same* type. But in general, it is not what C > variadic function(s) standing for. Because they stand for any number of > arguments, of any type. > In C, since all program is compiled statically, compiler knows the number > of passed arguments and their types through compiling each particular call > site(s) to variadic function. Which means that in fact, you are still > supplying all information needed by compiler *before* run time. > > In variadic functions, you can pass any arguments of any type, > but for converting each of them, you must tell NB what kind of marshaller > should be used for it , which means, that it is impossible to know before > run time, since you cannot know how many arguments you may pass, not > speaking about their types. > > > > >> Thanks, >> >> Matthieu >> >> >> > > > -- > Best regards, > Igor Stasenko. >