Oh shoot, I misunderstood something about the role of the extern-code.c file... I thought that it was being generated by the compiler for use at C compile+link-time. However, I now believe that it's actually being used by the clang-based front-end as a place to store and compile the extern blocks of C code themselves. This happens very early in compilation, which means that we haven't yet gotten to the codegen pass I was positing that could emit a header file of exported prototypes. :(
However, now that I understand it, this suggests another workaround (albeit a not-completely-satisfying one). In your extern C code block, if you add a C prototype for the routine that the Chapel compiler will create (which presumes you can anticipate what its C signature will be), you can add a C 'extern' declaration referring back to the Chapel routine that will appear later: extern double integrand(double x, void* ptr); Once I add this to your code, it compiles for me with the master branch of the project. It's worth noting that the generation of the header file of exported routines could help make this more bulletproof because if there was a disagreement between what the compiler created and what you expected it to create, the C compiler would complain at you (OTOH, it may also add fragility, as it doesn't take much to make some C compilers complain about differing prototypes -- like using different type aliases for the same underlying type).. I'll be curious if Michael (who developed the extern blocks) might have a smarter proposal than this one... I'm clearly learning on the job today. -Brad On Fri, 18 Mar 2016, Brad Chamberlain wrote: > > For the sake of the mailing list: > > Off-list, we confirmed that Nikhil is using 1.12. I remember hearing that > support for c_void_ptr had gotten better since the last release, and believe > that the difference we're seeing is the result of that. > > Meanwhile, I'm starting the process of taking a quick look into what it would > take to dump (at least simple) export'ed routines into their own header file > (and/or protecting things in chpl__header.h that can't afford to be #included > twice. (That said, I am close to timing out for the night). > > -Brad > > > On Fri, 18 Mar 2016, Nikhil Padmanabhan wrote: > >> Hi Brad, >> >> I'm missing something here. >> >> When I try >> chpl testit.chpl --savec output >> >> I get >> testit.chpl:12: error: illegal cast from c_void_ptr to c_ptr(R) >> >> It only has two files in the output directory --- it doesn't look like it >> even got to making the chpl__header.h file. >> >> Hm. >> -- Nikhil >> >> >> --------------------------------- >> Nikhil Padmanabhan >> [email protected] >> >> On Fri, Mar 18, 2016 at 7:17 PM, Brad Chamberlain <[email protected]> wrote: >> >>> >>> Hi Nikhil / all (Michael in particular may want to perk up as extern block >>> master) -- >>> >>> This may be a relatively simple fix. What I find (at least with my >>> version of gcc, which is... uh... Apple LLVM version 7.0.2) is that if I >>> compile with --savec on, the one thing that's missing is the prototype of >>> the 'export'ed function integrand within the 'extern block'ed code stored >>> in output/extern-code.c. That is, if I: >>> >>> * paste the code you mailed into testit.chpl >>> >>> * compile it with an LLVM-enabled copy of 'chpl' with: >>> >>> chpl testit.chpl --savec output >>> >>> * get the prototype for the export'ed function integrand: >>> >>> grep integrand output/chpl__header.h >>> >>> * paste it into the top of output/extern-code.c: >>> >>> <use your favorite editor> >>> >>> * recompile: >>> >>> make -f output/Makefile >>> >>> then things work for me (or at least the code compiles and generates: >>> >>> (alpha = 1.0) >>> >>> >>> If you can reproduce this, I think that the fix in the compiler would be >>> as simple as: >>> >>> * making sure to put all export'ed routines into a header of their own (we >>> should really be doing this anyway for other clients of the exported >>> routines... it's probably made slightly complicated by having to drag >>> over any types that they make use of as well >>> >>> * #include-ing that routine in any code files that we generate for >>> extern blocks >>> >>> >>> I'm working on reproducing with a second copy of Chapel, but it means >>> having to re-build LLVM... (zzzzz...) >>> >>> -Brad >>> >>> >>> >>> >>> >>> On Fri, 18 Mar 2016, Nikhil Padmanabhan wrote: >>> >>> Hi --- >>>> >>>> I'm trying to get a call-back from C into Chapel working -- where the >>>> intermediate C routine needs to pass through some data from the function >>>> that called it to the function it's calling. (To be specific, the C >>>> routine >>>> does a numerical integration and it's calling the integrand). >>>> >>>> The problem here is that the Chapel callback needs to convert the void* >>>> back into its original form. Note that it knows exactly what the correct >>>> form is -- but Chapel doesn't let me convert a c_void_ptr into >>>> anything..... >>>> >>>> Appended is a relatively simple program (using the extern block feature) >>>> that demonstrates the issue. Any thoughts on how to work around this >>>> would >>>> be great. Ideally, it would be nice to just reconvert the c_void_ptr into >>>> a >>>> c_ptr that can be dereferences... >>>> >>>> Thanks in advance! >>>> -- Nikhil >>>> >>>> use SysCTypes; >>>> >>>> record R { >>>> var alpha : real; >>>> // There could be more complicated things here >>>> // I could define this record in C, but it would be nice >>>> // not to do so. >>>> } >>>> >>>> export proc integrand(x : real, ptr : c_void_ptr) : real { >>>> // THE LINE BELOW DOESN'T WORK >>>> var p = ptr : c_ptr(R); // How do I get this, or equivalent to work >>>> var r = p.deref(); >>>> return r.alpha*x; >>>> } >>>> >>>> extern { >>>> static void integrate(void *p) { >>>> // A real integrator would do more >>>> double y; >>>> y = integrand(1,p); >>>> } >>>> } >>>> >>>> var r1 = new R(1.0); >>>> writeln(r1); >>>> var p1 = c_ptrTo(r1); >>>> integrate(p1:c_void_ptr); >>>> --------------------------------- >>>> Nikhil Padmanabhan >>>> [email protected] >>>> >>>> >> > ------------------------------------------------------------------------------ Transform Data into Opportunity. Accelerate data analysis in your applications with Intel Data Analytics Acceleration Library. Click to learn more. http://pubads.g.doubleclick.net/gampad/clk?id=278785231&iu=/4140 _______________________________________________ Chapel-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/chapel-users
