Hello Randy,

the following comes from my experience with ccall and Julia documentation.
Please anyone correct me if I explained any of the internals wrong!

The API seems to be really simple so pretty much everything can be done
with standard Julia types. Clang.jl seems to have generated correct code
for it.

Regarding 2, liboauth.dylib (or .dll, or .so on Linux) has to be loaded and
passed to ccall. You can load it by hand using dlopen, like this:

    liboauth = dlopen("/path/of/liboauth.dylib")

This will raise an error if the path is not valid. If the library is in
your environment's standard path, you can pass its name to ccall as a
string instead of creating a pointer with dlopen.

Most of the Ptr{Uint8} you got in the code generated by Clang.jl are
actually mapping char *, which are C strings (ASCII, not Unicode). For
example, let's say you wanted to call puts from libc, which is a function
that gets a string as its argument, prints it to the screen followed by a
newline, and returns the number of printed characters. You could do it like
this:

    ccall((:puts, "libc"), Cint, (Ptr{Uint8},), "Hello, Randy")

So, you basically can pass your string as the function argument and it
should work. You don't need to pass a pointer, but it's good to know that
your Julia ASCIIString was converted to Ptr{Uint8} internally.

With this you should be able to call functions, but you still need to be
able to recover their output. The second argument to ccall is the C
function return type, but note that often C functions do not return their
output in the return type, but in a variable which was passed by reference
as one of its arguments. I don't know enough of liboauth to know what's the
case, so you will need to check the documentation. See the sections
http://docs.julialang.org/en/release-0.3/manual/calling-c-and-fortran-code/#accessing-data-through-a-pointer
and
http://docs.julialang.org/en/release-0.3/manual/calling-c-and-fortran-code/#passing-pointers-for-modifying-inputs
for more details on that.

--
João Felipe Santos


On Sun, Aug 31, 2014 at 8:17 PM, Randy Zwitch <randy.zwi...@fuqua.duke.edu>
wrote:

> Hi all -
>
> I've been trying to learn more about C and how Julia interacts and decided
> to play around with Clang.jl. I decided I was going to wrap liboauth from
> here:
>
> http://liboauth.sourceforge.net/oauth_8h_source.html
>
> I downloaded the C source, which resided in my OSX Downloads directory.
> Using the following Julia code generated a bunch of output:
>
>  [1]:
>
> using Clang.wrap_c
>
> In [2]:
>
> context = wrap_c.init(; output_file="liboauth.jl", 
> header_library=x->"liboauth", common_file="liboauth.jl", 
> clang_diagnostics=true)
>
> context.options.wrap_structs = true
>
> wrap_c.wrap_c_headers(context, 
> ["/Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h"])
>
> WARNING: wrap_c_headers: deprecated
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:112:46: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:138:54: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:138:86: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:315:67: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:315:81: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:320:66: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:320:80: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:519:28: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:532:30: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:670:61: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:688:57: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:715:43: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:717:70: warning: type 
> specifier missing, defaults to 'int' [-Wimplicit-int]
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:717:77: warning: type 
> specifier missing, defaults to 'int' [-Wimplicit-int]
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:717:77: error: 
> redefinition of parameter 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:717:70: note: 
> previous declaration is here
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:741:24: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:771:43: error: 
> unknown type name 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:773:70: warning: type 
> specifier missing, defaults to 'int' [-Wimplicit-int]
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:773:77: warning: type 
> specifier missing, defaults to 'int' [-Wimplicit-int]
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:773:77: error: 
> redefinition of parameter 'size_t'
> /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h:773:70: note: 
> previous declaration is here
>
> WRAPPING HEADER: /Users/randyzwitch/Downloads/liboauth-1.0.3/src/oauth.h
>
> WARNING: Not wrapping MacroInstantiation   OA_GCC_VERSION_AT_LEAST
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
> WARNING: Not wrapping MacroInstantiation   attribute_deprecated
>
> writing liboauth.jl
>
> Out[2]:
>
> 1-element Array{Any,1}:
>  nothing
>
>
>
> Output:
>
>
> const LIBOAUTH_VERSION = "1.0.3"
> const LIBOAUTH_VERSION_MAJOR = 1
> const LIBOAUTH_VERSION_MINOR = 0
> const LIBOAUTH_VERSION_MICRO = 3
> const LIBOAUTH_CUR = 8
> const LIBOAUTH_REV = 7
> const LIBOAUTH_AGE = 8
>
> # Skipping MacroDefinition: OA_GCC_VERSION_AT_LEAST ( x , y ) ( __GNUC__ >
> x || __GNUC__ == x && __GNUC_MINOR__ >= y )
> # Skipping MacroDefinition: attribute_deprecated __attribute__ ( (
> deprecated ) )
>
> # begin enum ANONYMOUS_1
> typealias ANONYMOUS_1 Uint32
> const OA_HMAC = (uint32)(0)
> const OA_RSA = (uint32)(1)
> const OA_PLAINTEXT = (uint32)(2)
> # end enum ANONYMOUS_1
>
> # begin enum OAuthMethod
> typealias OAuthMethod Uint32
> const OA_HMAC = (uint32)(0)
> const OA_RSA = (uint32)(1)
> const OA_PLAINTEXT = (uint32)(2)
> # end enum OAuthMethod
> function oauth_sign_hmac_sha1(m::Ptr{Uint8},k::Ptr{Uint8})
>
> ccall((:oauth_sign_hmac_sha1,liboauth),Ptr{Uint8},(Ptr{Uint8},Ptr{Uint8}),m,k)
> end
>
> function
> oauth_sign_hmac_sha1_raw(m::Ptr{Uint8},ml::Cint,k::Ptr{Uint8},kl::Cint)
>
> ccall((:oauth_sign_hmac_sha1_raw,liboauth),Ptr{Uint8},(Ptr{Uint8},Cint,Ptr{Uint8},Cint),m,ml,k,kl)
> end
>
> function oauth_sign_plaintext(m::Ptr{Uint8},k::Ptr{Uint8})
>
> ccall((:oauth_sign_plaintext,liboauth),Ptr{Uint8},(Ptr{Uint8},Ptr{Uint8}),m,k)
> end
>
> function oauth_sign_rsa_sha1(m::Ptr{Uint8},k::Ptr{Uint8})
>
> ccall((:oauth_sign_rsa_sha1,liboauth),Ptr{Uint8},(Ptr{Uint8},Ptr{Uint8}),m,k)
> end
>
> function oauth_verify_rsa_sha1(m::Ptr{Uint8},c::Ptr{Uint8},s::Ptr{Uint8})
>
> ccall((:oauth_verify_rsa_sha1,liboauth),Cint,(Ptr{Uint8},Ptr{Uint8},Ptr{Uint8}),m,c,s)
> end
>
> <snip>
>
> My questions are:
>
> 1) Did I do this right? I got back a Julia file full of Julia code with
> ccalls, so it seems like I got back what was expected? There were lots of
> deprecation warnings in Julia however.
> 2) How do I actually start using this code for something? Other than
> unzipping the source code for liboauth, I haven't done anything with the C
> code other than generating the Julia ccalls. How will this Julia code know
> how to reference the original source liboauth.h file?
> 3) The Julia functions are using pointers as input types. Do I literally
> need to pass a pointer, or can I just provide the data type of the pointer
> (say, Uint8)?
>
> So, am I on the right track? What should I be thinking about if I want to
> take the next step in actually trying to use these functions?
>

Reply via email to