www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to use std. packages in so files written in dlang

reply grampus <grampusluan hotmail.com> writes:
Hi,erveryone
I am trying to use dLang to make so file for existing c/c++ 
project.
I followed the examples on https://dlang.org/dll-linux.html, 
which works well.

but when I replaced import core.stdc.stdio; with import std.stdio;
to use writefln() instead of printf(), then things changed.

compiling was still fine. so file still can be loaded.
But writefln() generated a error: "Segmentation fault (core 
dumped)"

I tried to search for solutions everywhere but nothing works.

BTW, in the command "dmd -oflibdll.so dll.o -shared 
-defaultlib=libphobos2.so 
-L-rpath=/path/to/where/shared/library/is" which path should I 
use for "/path/to/where/shared/library/is"? Tried some possible 
paths, none of them works. I compiled so file without "-L-rpath". 
At least for the examples still works

I am new to dLang. I hope I get help here.

Thanks in advance.
Aug 11 2016
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Friday, 12 August 2016 at 00:57:42 UTC, grampus wrote:

it's 'cause you didn't initialized druntime. you have to use 
dlsym to get "rt_init" function and call it right after loading 
your .so, but before calling any other API from it.

also, note that druntime is using SIGUSR1 and SIGUSR2 for it's 
internal housekeeping, so don't use this signals in your C++ code.
Aug 11 2016
parent reply grampus <grampusluan hotmail.com> writes:
On Friday, 12 August 2016 at 01:09:47 UTC, ketmar wrote:
 On Friday, 12 August 2016 at 00:57:42 UTC, grampus wrote:

 it's 'cause you didn't initialized druntime. you have to use 
 dlsym to get "rt_init" function and call it right after loading 
 your .so, but before calling any other API from it.

 also, note that druntime is using SIGUSR1 and SIGUSR2 for it's 
 internal housekeeping, so don't use this signals in your C++ 
 code.
Thank you for the quick reply. Do you mean that I have to do some changes on the C side? I can use dlang in this existing project as long as nothing can be changed on the C side. Do you think I can use dlang in our case? Thank you
Aug 11 2016
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 12 August 2016 at 01:36:34 UTC, grampus wrote:
 On Friday, 12 August 2016 at 01:09:47 UTC, ketmar wrote:
 On Friday, 12 August 2016 at 00:57:42 UTC, grampus wrote:

 it's 'cause you didn't initialized druntime. you have to use 
 dlsym to get "rt_init" function and call it right after 
 loading your .so, but before calling any other API from it.

 also, note that druntime is using SIGUSR1 and SIGUSR2 for it's 
 internal housekeeping, so don't use this signals in your C++ 
 code.
Thank you for the quick reply. Do you mean that I have to do some changes on the C side? I can use dlang in this existing project as long as nothing can be changed on the C side. Do you think I can use dlang in our case? Thank you
One way to handle this is to add initialize/terminate functions to your shared library. In that case, rather than rt_init, you can call the Runtime functions [1]: import core.runtime; extern(C) int initialize() { return Runtime.initialize(); } extern(C) int terminate() { return Runtime.terminate(); } From your C program, call initialize after loading the library and terminate before exiting. [1] http://dlang.org/phobos/core_runtime.html#.Runtime
Aug 11 2016
parent grampus <grampusluan hotmail.com> writes:
On Friday, 12 August 2016 at 01:45:29 UTC, Mike Parker wrote:
 On Friday, 12 August 2016 at 01:36:34 UTC, grampus wrote:
 On Friday, 12 August 2016 at 01:09:47 UTC, ketmar wrote:
 On Friday, 12 August 2016 at 00:57:42 UTC, grampus wrote:

 it's 'cause you didn't initialized druntime. you have to use 
 dlsym to get "rt_init" function and call it right after 
 loading your .so, but before calling any other API from it.

 also, note that druntime is using SIGUSR1 and SIGUSR2 for 
 it's internal housekeeping, so don't use this signals in your 
 C++ code.
Thank you for the quick reply. Do you mean that I have to do some changes on the C side? I can use dlang in this existing project as long as nothing can be changed on the C side. Do you think I can use dlang in our case? Thank you
One way to handle this is to add initialize/terminate functions to your shared library. In that case, rather than rt_init, you can call the Runtime functions [1]: import core.runtime; extern(C) int initialize() { return Runtime.initialize(); } extern(C) int terminate() { return Runtime.terminate(); } From your C program, call initialize after loading the library and terminate before exiting. [1] http://dlang.org/phobos/core_runtime.html#.Runtime
I will try this solution. One more question, if Runtime.initialize(); is called but when sofile is unloaded without calling Runtime.terminate(); is it going to cause any problem? for example so file is loaded again and again, Runtime.initialize() is called many times without Runtime.terminate().
Aug 11 2016
prev sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Friday, 12 August 2016 at 01:36:34 UTC, grampus wrote:
 I can use dlang in this existing project as long as nothing can 
 be changed on the C side.
then you have to check if runtime is initialized at the start of each function that can be called from C side. like this: private void ensureRuntimeInited () { static bool tlsinited = false; __gshared bool inited = false; if (!tlsinited) { synchronized(Object.classinfo) { if (!inited) { import core.runtime : Runtime; if (!Runtime.initialize) { import core.stdc.stdio : stderr, fprintf; import core.stdc.stdlib : abort; fprintf(stderr, "\nFATAL: failed to initialize druntime!\n"); abort(); } inited = true; } } tlsinited = true; } } extern(C) int myExtAPI () { ensureRuntimeInited(); // your D code here return 0; } yes, you have to do that in each exported function. as for your another question: if you won't call `rt_term()`, no module dtors will be called, no garbage will be collected at exit. there also may be problems with unregistering signal handlers, but i'm not sure. if you C app routinely loads and unloads .so without notifying it about the fact that .so is being unloaded, you are in big troubles not only with D, but with .so written in any other language. you *may* hack around this, but it's *WAY* better to fix your C app in this case.
Aug 11 2016
parent reply grampus <grampusluan hotmail.com> writes:
On Friday, 12 August 2016 at 02:31:29 UTC, ketmar wrote:
 On Friday, 12 August 2016 at 01:36:34 UTC, grampus wrote:
 [...]
then you have to check if runtime is initialized at the start of each function that can be called from C side. like this: [...]
Understand, I will be careful here. Thank you all for the quick feedback. Didn't realise the D community is such active. I hope D will be more popular Cheers
Aug 11 2016
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Friday, 12 August 2016 at 03:20:59 UTC, grampus wrote:
 Didn't realise the D community is such active.
yes, we are. while we may be not very huge in number, we are very passionate about our language of choice. ;-)
Aug 11 2016
parent reply bachmeier <no spam.net> writes:
On Friday, 12 August 2016 at 03:31:37 UTC, ketmar wrote:
 On Friday, 12 August 2016 at 03:20:59 UTC, grampus wrote:
 Didn't realise the D community is such active.
yes, we are. while we may be not very huge in number, we are very passionate about our language of choice. ;-)
Currently there are about 40,000 DMD downloads a month, so the community isn't terribly small. The forums see activity from a lot of different posters.
Aug 11 2016
parent ketmar <ketmar ketmar.no-ip.org> writes:
On Friday, 12 August 2016 at 03:41:54 UTC, bachmeier wrote:
 On Friday, 12 August 2016 at 03:31:37 UTC, ketmar wrote:
 On Friday, 12 August 2016 at 03:20:59 UTC, grampus wrote:
 Didn't realise the D community is such active.
yes, we are. while we may be not very huge in number, we are very passionate about our language of choice. ;-)
Currently there are about 40,000 DMD downloads a month, so the community isn't terribly small. The forums see activity from a lot of different posters.
sheer number of downloads doesn't say much. comparing to some other communities (let's talk about rust and go, for example, as relatively fresh performers on the stage) our community is small. but in the end it is quality that matters, not huge numbers, i believe. and signal/noise ratio of thing NG is great (especially when i'm not posting here).
Aug 11 2016
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Friday, 12 August 2016 at 00:57:42 UTC, grampus wrote:
 Hi,erveryone
 I am trying to use dLang to make so file for existing c/c++ 
 project.
 I followed the examples on https://dlang.org/dll-linux.html, 
 which works well.

 but when I replaced import core.stdc.stdio; with import 
 std.stdio;
 to use writefln() instead of printf(), then things changed.
To expand on ketmar's answer, support for some language features exists in D Runtime. If you never use those features directly or indirectly (which means limiting yourself to the C API, avoiding anything that touches the GC, no associative arrays, and so on) then you don't need to initialize D runtime. That's why you don't see the problem when calling printf, but writeln uses features internally that require the D Runtime and so you get the error when you execute the program.
Aug 11 2016