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-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 <[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{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