No, that’s all understood. For some reason, I just got the idea at some point that @ccall
defers to ccall
(instead of making an Expr(:foreigncall)
directly). Perhaps because of statements like these:
But they’re not the same! @ccall
can call varargs functions with arbitrary (mixed) types, whereas varargs arguments must all be of the same type with ccall
. These are equivalent:
julia> ccall(:printf, Cint, (Cstring, Cint...), "%d %d %d\n", 1, 2, 3);
1 2 3
julia> @ccall printf("%d %d %d\n"::Cstring; 1::Cint, 2::Cint, 3::Cint)::Cint;
1 2 3
But there’s no way to express the following using ccall
:
julia> @ccall printf("%d %f %s\n"::Cstring; 1::Cint, 2.0::Cdouble, "abc"::Cstring)::Cint;
1 2.000000 abc
(This is also stated in the documentation.)
Edited to add: I just realized there does seem to be one thing that ccall
can do and @ccall
can’t, which is specifying a calling convention? (Seems to be hard-coded to :ccall
, if I understand the code correctly.) Should be straightforward to add, but it’s not in the current implementation.