Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

callback to support possible vararg definitions? #17

Closed
amitmurthy opened this issue Mar 20, 2013 · 10 comments · Fixed by #315
Closed

callback to support possible vararg definitions? #17

amitmurthy opened this issue Mar 20, 2013 · 10 comments · Fixed by #315

Comments

@amitmurthy
Copy link
Contributor

Can wrap_c.init() take in an additional callback function which can be used to support varargs? i.e, can the callback function specify a list of possible vararg sets?
For example:

    CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); 

results in the wrong wrapper for curl_easy_setopt, i.e., a definition that takes in only the first 2 parameters. But this is mostly harmless.

But, it would be great if I could specify additional possible usage definitions like by providing a list of possible argument types (for the varargs) as sublists like this - [[Int32, Ptr{:Uint8}], [Int32], [ Ptr{:Uint8}]].

For example the possible actual usage scenarios for curl_easy_setopt are

CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, long val);
CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, char * val);
CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, void * p);

So, in the above case I could just specify the possibilities for the 3rd parameter.

@ihnorton
Copy link
Collaborator

Related to #7. Since Julia supports varargs in ccall, I think I can support this without generating multiple type-distinct function signatures. I just need to detect it and pass the correct incantation to ccall. Would this be sufficient?

@amitmurthy
Copy link
Contributor Author

Should work.

Do note that libCURL header files use an ellipsis (...) to specify varargs (http://en.wikipedia.org/wiki/Variadic_function#C.2C_Objective-C.2C_C.2B.2B.2C_and_D) . As long as clang has the same behavior for both an ellipsis as well as the older "va_list" argument type, it should be OK.

@vtjnash
Copy link
Collaborator

vtjnash commented Mar 21, 2013

A va_list and a ... argument are not the same argument type (the link refers to the name of the header being old, not the contents). Both are very difficult to generate dynamically, so neither is supported very well by julia currently. The platform ABI can get very tricky here.

@ihnorton
Copy link
Collaborator

Ah, ok. Thanks for the explanation. I didn't dig into this yet - had thought va_list was fully supported and didn't realize there was another kind. So I guess even generating unique signature/ccall pairings will not work. "cantfix" for now.

@amitmurthy
Copy link
Contributor Author

Generating unique ccall pairings will work in the context of libCURL at least. For example my module file looks like this

module libCURL

include("lC_exports_h.jl")
include("lC_common_h.jl")

@ctypedef time_t Int32
@ctypedef CURLMcode Int32

include("lC_curl_h.jl")

@c CURLcode curl_easy_setopt (Ptr{:CURL},:CURLoption,:Int) :libcurl
@c CURLcode curl_easy_setopt (Ptr{:CURL},:CURLoption,Ptr{:Void}) :libcurl
@c CURLcode curl_easy_setopt (Ptr{:CURL},:CURLoption,Ptr{:Uint8}) :libcurl

@c CURLcode curl_easy_getinfo (Ptr{:CURL},:CURLoption,Ptr{:Int}) :libcurl
@c CURLcode curl_easy_getinfo (Ptr{:CURL},:CURLoption,Ptr{:Float64}) :libcurl
@c CURLcode curl_easy_getinfo (Ptr{:CURL},:CURLoption,Ptr{:Uint8}) :libcurl

include("lC_defines_h.jl")

end

where
lC_exports_j.jl is a file containing all the exports (generated by parsing lC_common_h.jl and lC_curl_h.jl)
lC_common_h.jl are the enum consts (generated by clang.jl)
lC_curl_h.jl are the @c entries for the functions (generated by clang.jl)
lC_defines_h.jl has the '#define' s (generated using the standard C preprocessor and regex)

I would not be able to use libCURL without the extra definitions for curl_easy_setopt and curl_easy_getinfo, but I can get by by defining the few functions that require the same manually.

A work in progress but you can check it out at https://github.com/amitmurthy/libCURL.jl

@vtjnash
Copy link
Collaborator

vtjnash commented Mar 21, 2013

The x64 ABI states that this will not necessarily generate valid code, unless you declare that this is a varargs call (with ...). Notably the RAX register may contain an invalid value.
Instead, this should be sufficient:
@c CURLcode curl_easy_setopt (Ptr{:CURL},:CURLoption,:Int...) :libcurl

@amitmurthy
Copy link
Contributor Author

Thanks.

@c CURLcode curl_easy_setopt (Ptr{:CURL},:CURLoption,:(Int...)) :libcurl

works. Notice I had to put a () around Int...

But I am having problems specifying an ellipsis for Ptr{:Float64} ?
:(Ptr{:Float64}...) and variations on the theme don't work.

@vtjnash
Copy link
Collaborator

vtjnash commented Mar 21, 2013

I'm not sure if that means that same thing with (), but I don't know how it gets expanded in the @c macro
In the final form, it should look something like ccall((:curl_easy_setopt,lib), (Ptr{CURL},CURLoption,Int...), arg1, arg2, arg3)

@ihnorton
Copy link
Collaborator

You might have to write that out completely at the moment... I can't check on this right now, but I doubt it will work with the macro as-is.

I will (very soon) make the generator print all types without nested symbols, then the @c macro will be able to take all arguments literally (eliminating the eval funny business). At that point it should be possible to use the macro directly for this.

@amitmurthy
Copy link
Contributor Author

Cool. Thanks.

@ihnorton ihnorton reopened this Sep 12, 2013
@Gnimuc Gnimuc mentioned this issue Mar 30, 2019
10 tasks
@Gnimuc Gnimuc added this to the release-0.14.0 milestone May 13, 2021
melonedo pushed a commit to melonedo/Clang.jl that referenced this issue Jul 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants