This C interface stuff is definitely sometimes a bit tricky and awkward
here and there. I think we're mostly winning in that the advanced features
are doable at all, but improvements are certainly possible and and good
ideas would be most welcomed. Glad that you're enjoying the rest of the
language :-)


On Sun, Aug 10, 2014 at 11:16 PM, Kevin Squire <[email protected]>
wrote:

> Thanks Gerry!
>
> As a point of reference, I'm working on wrapping ffmpeg/libav right now.
>  One of the things that I do is pass a pointer to a Julia object as a void
> pointer (using `pointer_to_objref` here:
> https://github.com/kmsquire/AV.jl/blob/kms/io_refactor/src/avio.jl#L209-L211).
>  This is then passed as a Void pointer to a call back here:
> https://github.com/kmsquire/AV.jl/blob/kms/io_refactor/src/avio.jl#L178-L182
> ).
>
> Even though it's supposed to be a Ptr{Void}, I have no problem calling it
> a Ptr{AVInput} in Julia, and as long as it is actually an AVInput, I can
> turn that pointer into the actual object with `unsafe_pointer_to_objref`
> (which I do).
>
> These are actual Julia objects, not arrays, so it doesn't match your use
> case exactly, but it shows what is possible.
>
> Some of the shenanigans I've had to jump through for libav haven't really
> been that fun.  For example, libav uses a lot of references to pointers or
> pointers to pointers.  In Julia, to use these, I have to make an array of
> pointers (with one element) and pass that to the function.  Feels kinda
> kudgy, but at least it's doable.  Rumor has it that an actual Ref type
> might be available in the future, to make these kinds of things easier.
>
> Anyway,  I'm glad to hear you're enjoying Julia!  Most of us who have been
> here for a little while feel the same way.
>
> Cheers!
>
>    Kevin
>
>
>
> On Sun, Aug 10, 2014 at 7:51 PM, Gerry Weaver <[email protected]> wrote:
>
>> Hello All,
>>
>> I felt like I should summarize my experience on this for the benefit of
>> others. I also didn't want to leave a negative impression regarding the
>> Julia language. Julia is by far the best and most interesting high level
>> language that I have ever used. It makes all of the things I love about
>> Lisp much more practical for general day to day use. I'm very positive
>> about Julia overall, and I'm enjoying using it a lot.
>>
>> The only way I could get more complex data types working from
>> Julia->C->Julia is to provide the appropriate type declarations to ccall
>> and cfunction. Unfortunately, I was looking to hide the C interface from
>> the api user and the need to specify the type makes that more difficult.
>> However, it did occur to me that I could wrap ccall and cfunction in a
>> Julia function that would look at the argument type and do the appropriate
>> thing with ccall/cfunction. So... in fairness, it DOES work. It just
>> doesn't work the way I wanted it to. I just wanted to set the record
>> straight on that fact.
>>
>> Thanks,
>> -G
>>
>>
>>
>> On Sunday, August 10, 2014 4:47:09 PM UTC-5, Kevin Squire wrote:
>>
>>> Okay, no worries!
>>>
>>>
>>> On Sun, Aug 10, 2014 at 2:38 PM, Gerry Weaver <[email protected]> wrote:
>>>
>>>> Hi Kevin,
>>>>
>>>> I had already tried something similar to what you propose, but neither
>>>> version works. Hence my confusion. println in either case just prints
>>>> garbage. It does compile though. I was hoping to be able to hide some of
>>>> this C callback complexity from the api user. It's beginning to look like
>>>> that would be difficult to do. I haven't really had the chance to think
>>>> through what a macro might provide though. In any case, I think the C
>>>> version ends up being much more straight forward. I'm going to stop
>>>> bothering you guys with this. There are many other areas in Julia to
>>>> explore ;) Thanks for your help and patience.
>>>>
>>>> Thanks,
>>>> -G
>>>>
>>>>
>>>> On Sunday, August 10, 2014 3:02:16 PM UTC-5, Kevin Squire wrote:
>>>>
>>>>> More specifically, you can at least do the following:
>>>>>
>>>>> function my_callback(_cbdata::Ptr{Void})
>>>>>     cbdata = reinterpret(Ptr{Ptr{Uint8}}, _cbdata)  # equivalent to
>>>>> casting
>>>>>     arr = pointer_to_array(cbdata, 4) # arr of length 4
>>>>>     println(bytestring(arr[1]))
>>>>>     nothing
>>>>> end
>>>>>
>>>>> cbfunc = cfunction(my_callback, Void, (Ptr{Void},))
>>>>>
>>>>> Although I think the previous version might work (did you try
>>>>> it?)--Julia can't tell a Ptr{Void} from a Ptr{Ptr{Uint8}} when called from
>>>>> C, and the C routine just trusts that you're passing a function which 
>>>>> takes
>>>>> a void pointer--it also can't check the type of the Julia function.
>>>>>
>>>>> Cheers,
>>>>>    Kevin
>>>>>
>>>>>
>>>>> On Sun, Aug 10, 2014 at 12:47 PM, Stefan Karpinski <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> This is absolutely possible. You can take any pointer and turn it
>>>>>> into an array. The only concern is garbage collection and making sure 
>>>>>> that
>>>>>> Julia knows whether it should free the memory or not.
>>>>>>
>>>>>> On Aug 10, 2014, at 3:31 PM, Gerry Weaver <[email protected]> wrote:
>>>>>>
>>>>>> Hi Kevin,
>>>>>>
>>>>>> It probably would, but in this case the C function takes a void
>>>>>> pointer argument and passes that to the Julia callback function.
>>>>>> Unfortunately, I can't change the type of the argument. I was hoping that
>>>>>> there was a way to convert that void pointer back to an array, but it 
>>>>>> isn't
>>>>>> looking like that is possible. I guess the answer is to pass a blob of 
>>>>>> text
>>>>>> with some type of delimiter to pass multiple values. That would be
>>>>>> significantly slower though.
>>>>>>
>>>>>> Thanks,
>>>>>> -G
>>>>>>
>>>>>> On Sunday, August 10, 2014 10:56:23 AM UTC-5, Kevin Squire wrote:
>>>>>>>
>>>>>>> Hi Gerry,
>>>>>>>
>>>>>>> I think I see whats going on. If the pointer that is being passed to
>>>>>>>> pointer_to_array is void, then you get a array of void pointers. In my 
>>>>>>>> case
>>>>>>>> the original array was an array of strings, so...
>>>>>>>>
>>>>>>>> arr = pointer_to_array(cbdata, 4, true)
>>>>>>>> println(bytestring(convert(Ptr{Uint8}, val[1])))
>>>>>>>>
>>>>>>>
>>>>>>> Was the original array of strings allocated by Julia, or in your C
>>>>>>> function?
>>>>>>>
>>>>>>> I think your solution is close.  It would be slightly cleaner if you
>>>>>>> declared you function to take a Ptr{Ptr{Uint8}}:
>>>>>>>
>>>>>>> function my_callback(cbdata::Ptr{Ptr{Uint8}})
>>>>>>>     arr = pointer_to_array(cbdata, 4) # arr of length 4
>>>>>>>     println(bytestring(arr[1]))
>>>>>>>     nothing
>>>>>>> end
>>>>>>>
>>>>>>> cbfunc = cfunction(my_callback, Void, (Ptr{Ptr{Uint8}},))
>>>>>>>
>>>>>>> Does this work?
>>>>>>>
>>>>>>> BTW, have you seen Steven Johnson's blog post on Passing Julia
>>>>>>> Callback Functions to C
>>>>>>> <http://julialang.org/blog/2013/05/callback/>?  I've found it quite
>>>>>>> useful.
>>>>>>>
>>>>>>> Cheers!
>>>>>>>    Kevin
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> Is there a better way to do this?
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> -G
>>>>>>>>
>>>>>>>>
>>>>>>>> On Sunday, August 10, 2014 4:23:29 AM UTC-5, Gerry Weaver wrote:
>>>>>>>>>
>>>>>>>>> Hi Kevin,
>>>>>>>>>
>>>>>>>>> I found the pointer_to_array function, but I'm having some trouble
>>>>>>>>> figuring how to call it correctly. I assume it has something to do 
>>>>>>>>> with the
>>>>>>>>> pointer being a void pointer. I've been searching for something that 
>>>>>>>>> might
>>>>>>>>> give me a clue how to do this, but I haven't found anything very 
>>>>>>>>> useful so
>>>>>>>>> far.
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> -G
>>>>>>>>>
>>>>>>>>> On Sunday, August 10, 2014 4:06:52 AM UTC-5, Kevin Squire wrote:
>>>>>>>>>>
>>>>>>>>>> Hi Gerry,
>>>>>>>>>>
>>>>>>>>>> "pointer_to_array" is probably what you're looking for.  See
>>>>>>>>>> http://julia.readthedocs.org/en/latest/manual/calling-c
>>>>>>>>>> -and-fortran-code/#accessing-data-through-a-pointer for more
>>>>>>>>>> information.
>>>>>>>>>>
>>>>>>>>>> Cheers,
>>>>>>>>>>    Kevin
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Sun, Aug 10, 2014 at 1:17 AM, Gerry Weaver <[email protected]>
>>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>>> I forgot to mention that I'm trying to accomplish this with
>>>>>>>>>>> arrays right now. I can pass a Julia array to C and access it 
>>>>>>>>>>> there, but I
>>>>>>>>>>> can't figure out how to convert it back to a Julia array from a C 
>>>>>>>>>>> void
>>>>>>>>>>> pointer when calling back to Julia from C.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Sunday, August 10, 2014 1:57:18 AM UTC-5, Gerry Weaver wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> Hello All,
>>>>>>>>>>>>
>>>>>>>>>>>> I have a C function called mycfunc that takes a callback
>>>>>>>>>>>> function pointer (cbfunc) and a void pointer (cbdata) as 
>>>>>>>>>>>> arguments. mycfunc
>>>>>>>>>>>> calls the callback function (cbfunc) passing the void pointer 
>>>>>>>>>>>> (cbdata) as
>>>>>>>>>>>> its argument. I'm trying to figure out how to pass a Julia type as 
>>>>>>>>>>>> the void
>>>>>>>>>>>> pointer argument and convert it back to the Julia type in the Julia
>>>>>>>>>>>> function passed as the callback function argument. I can do this 
>>>>>>>>>>>> with a
>>>>>>>>>>>> simple string, but I'm having some difficulty in figuring out how 
>>>>>>>>>>>> to do it
>>>>>>>>>>>> with arrays and other types. Any advice on this would be much 
>>>>>>>>>>>> appreciated.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> typedef int (* mycallback)(void *cbdata);
>>>>>>>>>>>>
>>>>>>>>>>>> void mycfunc(mycallback cbfunc, void *cbdata)
>>>>>>>>>>>> {
>>>>>>>>>>>>   cbfunc(cbdata);
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> -G
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>
>>>>>
>>>
>

Reply via email to