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] > <javascript:>> 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 >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>> >>>>> >>> >
