> varargs is not part of the ABI standard
varargs are generally part of the ABI standards that I have read (although
it seems that va_arg is typically not)

However, it should be warned that the varargs part of the standard is clear
that it is not equivalent to declaring a function with the fully expanded
argument list. Therefore, Tim's code above is only correct for platforms
where this happened to be the case (e.g. x86 and older ARM devices). Julia
currently only handles a subset of the full varargs functionality, where
all varargs arguments must be of the same type:
ccall(:fcn, RetType, (Arg1Ty, Arg2Ty, ArgNTy...), arg1, arg2, arg3, argn1,
argn2, arn3)

My most recent Julep (https://github.com/JuliaLang/julia/issues/6661) is
still waiting for comments before I start implementation.


On Tue, Jun 10, 2014 at 11:02 PM, Tim Holy <[email protected]> wrote:

> I once built a Julia varargs-to-C varargs function, which even though there
> was a better way to accomplish the same goal, I saved as an example for
> myself
> in case I needed it in the future. See if it's helpful to you.
>
> --Tim
>
> const GtkFileChooserDialogDict = Dict{Int, Function}()  # for varargs ccall
> type GtkFileChooserDialog <: GtkDialogI
>     handle::Ptr{GObject}
>     function GtkFileChooserDialog(title::String,
> parent::Union(GtkWindow,Ptr{Void}), action::Integer,
> button_text_response...)
>         n = length(button_text_response)
>         if !iseven(n)
>             error("button_text_response must consist of text/response
> pairs")
>         end
>         npairs = div(n, 2)
>         if !haskey(GtkFileChooserDialogDict, npairs)
>             # Build a function expression that makes ccall with explicit
> args
> of correct types
>             ctypeexpr = Expr(:tuple,Ptr{Uint8},Ptr{Void},Cint,ntuple(n,i-
> >isodd(i) ? Ptr{Uint8} : Cint)...,Ptr{Void})
>             argnameexpr = Expr(:tuple,:title,:parent,:action,Expr(:...,
> :button_text_response))
>             argvalexpr =
> tuple(:title,:(anonp(parent)),:action,ntuple(n,i->:
> (button_text_response[$i]))...,:C_NULL)
>             ex = Expr(:function, argnameexpr, Expr(:ccall,
>                                                    :
> (:gtk_file_chooser_dialog_new,libgtk),
>                                                    :(Ptr{GObject}),
>                                                    ctypeexpr,
>                                                    argvalexpr...))
>             GtkFileChooserDialogDict[npairs] = eval(ex)
>         end
>         hnd = GtkFileChooserDialogDict[npairs](title, parent, action,
> button_text_response...)
>         widget = gc_ref(new(hnd))
>         gtk_doevent()
>         show(widget)
>         widget
>     end
> end
>
>
> On Tuesday, June 10, 2014 03:09:31 PM J Luis wrote:
> > Hi,
> >
> > How would I turn this C function prototype into a ccall?
> >
> > Ihandle* IupVbox(Ihandle **child*, ...);
> >
> > The varargs here mean that all but last optional arguments are of the
> same
> > type a `child`. The last one must be NULL.
> > Let me also add that Clang.jl skipped these type of declarations
>

Reply via email to