www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - Shared library with C API

reply Etienne Cimon <etcimon gmail.com> writes:
I'm a little new to the LLVM / LDC world, I'm looking forward to 
compiling a library with a C API that could be linked from not only D 
but also C or C++ project (through LLVM as well possibly).

I'm wondering if someone knows if this is something that's currently 
possible.

Thanks!
May 24 2014
parent reply "Kagamin" <spam here.lot> writes:
Should be possible:

extern(C)
int callme(int a)
{ return a; }
May 25 2014
parent reply "Kai Nacke" <kai redstar.de> writes:
On Sunday, 25 May 2014 at 10:27:50 UTC, Kagamin wrote:
 Should be possible:

 extern(C)
 int callme(int a)
 { return a; }
Yes, right. There is nothing special in using LDC here. There is even a recipe in the new D Cookbook on this topic (chapter 4, "Write part of a C proram in D"). Don't forget to initialize the D runtime from your C/C++ program. Regards, Kai
May 25 2014
parent reply Etienne Cimon <etcimon gmail.com> writes:
On 2014-05-26 02:16, Kai Nacke wrote:
 There is even a recipe in
 the new D Cookbook on this topic (chapter 4, "Write part of a C proram
 in D").
I'm waiting to get my copy ;)
 Don't forget to initialize the D runtime from your C/C++ program.
Would that mean I have to call rt_init() at the start of every function?
May 26 2014
next sibling parent "Chris" <wendlec tcd.ie> writes:
On Monday, 26 May 2014 at 12:50:59 UTC, Etienne Cimon wrote:
 On 2014-05-26 02:16, Kai Nacke wrote:
 There is even a recipe in
 the new D Cookbook on this topic (chapter 4, "Write part of a 
 C proram
 in D").
I'm waiting to get my copy ;)
 Don't forget to initialize the D runtime from your C/C++
program. Would that mean I have to call rt_init() at the start of every function?
Do you mean calling D from C(++)? Ideally you call rt_init() only once, that's what I did when I wrote Python modules in C that linked to D code (C was only a thin wrapper). But I don't know how your program / application is structured.
May 26 2014
prev sibling parent reply "Kai Nacke" <kai redstar.de> writes:
Hi Etienne!

On Monday, 26 May 2014 at 12:50:59 UTC, Etienne Cimon wrote:
 On 2014-05-26 02:16, Kai Nacke wrote:
 Would that mean I have to call rt_init() at the start of every 
 function?
No. Just call rt_init() before you call the first D function. You should also call rt_term() e.g. on program shutdown. This makes sure that the D runtime is initialized properly and that resources are freed on shutdown. You should also make sure that no D exception escapes as C has no exception handling and D exceptions are not compatible with C++ exceptions. Regards, Kai
May 26 2014
parent reply Etienne <etcimon gmail.com> writes:
On 2014-05-26 12:33 PM, Kai Nacke wrote:
 No. Just call rt_init() before you call the first D function. You should
 also call rt_term() e.g. on program shutdown. This makes sure that the D
 runtime is initialized properly and that resources are freed on shutdown.
 You should also make sure that no D exception escapes as C has no
 exception handling and D exceptions are not compatible with C++ exceptions.

 Regards,
 Kai
I looked at the p.97 in the D Cookbook, and it calls rt_init() from C. I was wondering, isn't it easier to put this initialization in a static this(), in the D module directly? e.g. in test.d import std.stdio, core.stdc.stdio : stderr; extern(C) void helloC() nothrow; // a function from C extern(C) void helloD() nothrow { helloC(); try { writeln("hello from D!"); } catch(Throwable t) { fprintf(stderr, "writeln threw an exception.\n"); } } static this(){ rt_init(); }
May 30 2014
next sibling parent "Dicebot" <public dicebot.lv> writes:
On Friday, 30 May 2014 at 17:37:04 UTC, Etienne wrote:
 On 2014-05-26 12:33 PM, Kai Nacke wrote:
 No. Just call rt_init() before you call the first D function. 
 You should
 also call rt_term() e.g. on program shutdown. This makes sure 
 that the D
 runtime is initialized properly and that resources are freed 
 on shutdown.
 You should also make sure that no D exception escapes as C has 
 no
 exception handling and D exceptions are not compatible with 
 C++ exceptions.

 Regards,
 Kai
I looked at the p.97 in the D Cookbook, and it calls rt_init() from C. I was wondering, isn't it easier to put this initialization in a static this(), in the D module directly?
AFAIK module constructors are called by runtime, so with absence of rt_init() those will have no effect.
May 31 2014
prev sibling parent reply "Ellery Newcomer" <ellery-newcomer utulsa.edu> writes:
On Friday, 30 May 2014 at 17:37:04 UTC, Etienne wrote:
 I was wondering, isn't it easier to put this initialization in 
 a static this(), in the D module directly?
no. use pragma(LDC_global_crt_ctor). fyi pyd builds shared libraries in the same way you want to https://bitbucket.org/ariovistus/pyd/src/7fe2f9cf98da2fbd2b26bb30a5d93245c25ec742/infrastructure/d/python_so_linux_boilerplate.d?at=default
Jun 02 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
"Ellery Newcomer" <ellery-newcomer utulsa.edu> writes:

 On Friday, 30 May 2014 at 17:37:04 UTC, Etienne wrote:
 I was wondering, isn't it easier to put this initialization in a
 static this(), in the D module directly?
no. use pragma(LDC_global_crt_ctor). fyi pyd builds shared libraries in the same way you want to https://bitbucket.org/ariovistus/pyd/src/7fe2f9cf98da2fbd2b26bb30a5d93245c25ec742/infrastructure/d/python_so_linux_boilerplate.d?at=default
LDC also uses global ctors to build the ModuleInfo list. A problem with calling rt_init() in a global ctor means that ModuleInfo is probably incomplete, meaning some or no module ctors (static this) are called. I thought perhaps the LDC_global_crt_ctor optional priority arg could help, but makes no difference on OSX at least. -- Dan
Jun 04 2014
parent reply "Ellery Newcomer" <ellery-newcomer utulsa.edu> writes:
On Wednesday, 4 June 2014 at 15:18:22 UTC, Dan Olson wrote:
 LDC also uses global ctors to build the ModuleInfo list.  A 
 problem with
 calling rt_init() in a global ctor means that ModuleInfo is 
 probably
 incomplete, meaning some or no module ctors (static this) are 
 called.  I
 thought perhaps the LDC_global_crt_ctor optional priority arg 
 could
 help, but makes no difference on OSX at least.
haven't noticed this on linux. I have noticed that druntime does not like it when you call rt_init or rt_term more than once, which kind of precludes multiple shared libs with this scheme.
Jun 05 2014
parent reply Dan Olson <zans.is.for.cans yahoo.com> writes:
"Ellery Newcomer" <ellery-newcomer utulsa.edu> writes:

 On Wednesday, 4 June 2014 at 15:18:22 UTC, Dan Olson wrote:
 LDC also uses global ctors to build the ModuleInfo list.  A problem
 with
 calling rt_init() in a global ctor means that ModuleInfo is probably
 incomplete, meaning some or no module ctors (static this) are
 called.  I
 thought perhaps the LDC_global_crt_ctor optional priority arg could
 help, but makes no difference on OSX at least.
haven't noticed this on linux. I have noticed that druntime does not like it when you call rt_init or rt_term more than once, which kind of precludes multiple shared libs with this scheme.
Hmmm, rt_init/rt_term source looks like it is designed to be called multiple times. Is it because LDC currently only has runtime as static lib so each of your shared libs has own copy of runtime? I bet it will work once LDC has shared lib runtime/phobos. http://forum.dlang.org/post/mailman.94.1396646137.19942.digitalmars-d-ldc puremagic.com
Jun 05 2014
parent reply "Ellery Newcomer" <ellery-newcomer utulsa.edu> writes:
On Friday, 6 June 2014 at 05:52:21 UTC, Dan Olson wrote:
 Hmmm, rt_init/rt_term source looks like it is designed to be 
 called
 multiple times.
oo. this is new. looks like it happened here https://github.com/D-Programming-Language/druntime/commit/cd42380a568c41c2b9bd2e1d14c39c4fdc8c859e time to dust off pyd and try this use case again.
Jun 06 2014
parent "Ellery Newcomer" <ellery-newcomer utulsa.edu> writes:
On Friday, 6 June 2014 at 13:00:42 UTC, Ellery Newcomer wrote:
 On Friday, 6 June 2014 at 05:52:21 UTC, Dan Olson wrote:
 Hmmm, rt_init/rt_term source looks like it is designed to be 
 called
 multiple times.
oo. this is new. looks like it happened here https://github.com/D-Programming-Language/druntime/commit/cd42380a568c41c2b9bd2e1d14c39c4fdc8c859e time to dust off pyd and try this use case again.
by gumbo, it works
Jun 06 2014