Try adding `const` in front of `liboauth = dlopen( "/usr/local/lib/liboauth.dylib")`.
Cheers, Kevin On Mon, Sep 1, 2014 at 1:24 PM, Randy Zwitch <[email protected]> wrote: > Thanks for the suggestions everyone. Unfortunately, neither the code from > Ivar nor João worked for me. > > liboauth = dlopen("/usr/local/lib/liboauth.dylib") > > Out[8]: > > > Ptr{Void} @0x00007fdc665c5ca0 > > In [9]: > > function oauth_sign_hmac_sha1(m::String,k::String) > > > res = > ccall((:oauth_sign_hmac_sha1,liboauth),Ptr{Uint8},(Ptr{Uint8},Ptr{Uint8}),m,k) > > > if res == C_NULL > > > error("oauth_sign_hmac_sha1 failed") > > > end > > > return string(res) > > end > > > > > testurl = > "GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal" > > testkey = "kd94hf93k423kf44&pfkkdhi9sl3r4s00" > > oauth_sign_hmac_sha1(testurl, testkey) > > > type: oauth_sign_hmac_sha1: in ccall: first argument not a pointer or valid > constant expression, expected DataType, got Type{(Any...,)} > while loading In[9], in expression starting on line 11 > > in oauth_sign_hmac_sha1 at In[9]:2 > > > > > testurl = > "GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal" > > testkey = "kd94hf93k423kf44&pfkkdhi9sl3r4s00" > > b64d = ccall((:oauth_sign_hmac_sha1, liboauth), Ptr{Uint8}, (Ptr{Uint8}, > Ptr{Uint8}), testurl, testkey) > > bytestring(b64d) > > > type: anonymous: in ccall: first argument not a pointer or valid constant > expression, expected DataType, got Type{(Any...,)} > while loading In[10], in expression starting on line 3 > > in anonymous at no file > > > Does this mean I compiled the library wrong? When I did the 'make' step, > after it was complete, I did 'make installcheck' and the 3 tests reported > that they completed successfully. > > At a higher level, I like Isaiah's suggestion of doing this process by > hand to really get to understanding what is going on. Is there an eaier > external library that one of you could suggest that I could use to walk > through the entire process? I've done the examples in the manual using > :clock and :getenv and understand what is going on, so now I want to work > with a user-installed library to make sure I really get the process. I > started with OAuth to see if I could make something usable to work with my > Twitter package, but maybe it's not the best starting place. > > > On Monday, September 1, 2014 10:47:22 AM UTC-4, João Felipe Santos wrote: > >> You need to do ccalls using Ptr{Uint8}. What you can do actually is wrap >> the Clang.jl-generated functions with your own functions with an >> alternative signature, and then convert from ASCIIString to Ptr{Uint8}. >> Note that you probably will need to do it anyways to wrap the return types, >> since you probably do not want to work with pointers from Julia :) >> >> In that specific example, if m and k are ASCIIStrings, conversions will >> be done automatically: >> >> testurl = "GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file% >> 3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_ >> nonce%3Dkllo9940pd9333jh%26oauth_signature_method% >> 3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token% >> 3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal" >> testkey = "kd94hf93k423kf44&pfkkdhi9sl3r4s00" >> b64d = ccall((:oauth_sign_hmac_sha1, liboauth), Ptr{Uint8}, >> (Ptr{Uint8}, Ptr{Uint8}), testurl, testkey) >> >> Note that b64d here will be a Ptr{Uint8}, which you can convert to a >> Julia string by using bytestring(b64d). >> >> -- >> João Felipe Santos >> >> >> On Mon, Sep 1, 2014 at 9:55 AM, Randy Zwitch <[email protected]> >> wrote: >> >>> To make it a bit more concrete, the C library has this test function: >>> >>> testurl = "GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3D" >>> "vacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_ >>> nonce" >>> "%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26o" >>> "auth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk" >>> "%26oauth_version%3D1.0%26size%3Doriginal"; >>> testkey = "kd94hf93k423kf44&pfkkdhi9sl3r4s00"; >>> b64d = oauth_sign_hmac_sha1(testurl , testkey); >>> >>> In Julia, I have this generated from Clang.jl: >>> >>> liboauth = dlopen("/usr/local/lib/liboauth.dylib") >>> >>> 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 >>> >>> What modifications do I need to make to the Clang Julia code to run this >>> test? >>> >>> >>> >>> On Monday, September 1, 2014 8:54:59 AM UTC-4, Randy Zwitch wrote: >>>> >>>> Thanks for the detailed response João! As it turns out, I didn't have >>>> any .dylib files as part of the downloaded code, but I was able to figure >>>> out how to compile the code and I believe I've got the library installed >>>> locally now. >>>> >>>> When you reference that most of my Ptr{Uint8} values are really just >>>> looking for string inputs, can I modify the Julia function signature to >>>> take ::ASCIIString instead? Or is this something where I have the leave the >>>> type signatures as they are, but understand what the function is actually >>>> looking for from the documentation? >>>> >>>> On Sunday, August 31, 2014 9:19:21 PM UTC-4, João Felipe Santos wrote: >>>>> >>>>> 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-an >>>>> d-fortran-code/#accessing-data-through-a-pointer and >>>>> http://docs.julialang.org/en/release-0.3/manual/calling-c-an >>>>> d-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 < >>>>> [email protected]> 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{U >>>>>> int8},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{Uin >>>>>> t8}) >>>>>> 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? >>>>>> >>>>> >>>>> >>
