Thread overview
Linking C++ with a D-library
Jun 26, 2013
Milvakili
Jun 26, 2013
Adam D. Ruppe
Jun 26, 2013
Milvakili
Jun 26, 2013
Justin Whear
Jun 26, 2013
Milvakili
Jun 26, 2013
Adam D. Ruppe
Jun 27, 2013
Milvakili
Jun 27, 2013
Adam D. Ruppe
June 26, 2013
Hi, I'm a new to D and I could not find any relevant answers in the forum.

I want to call functions from D-lib from c++ main.
dlibrary

import std.stdio;

extern (C++) void foo(int i, int j, int k) {
  writefln("i = %s", i);
  writefln("j = %s", j);
  writefln("k = %s", k);
}
void main(){}

######
c++ binary

#include <iostream>

void CXXmain();
void foo(int i, int j, int k);
using namespace std;

int main(){
  cout << "This is the main of C++\n";
  foo(1,3,4);
  return 0;
}

####
I can compile d with dmd and c++ with g++ then linked them with g++.  The problem is when I run the binary I got:

> ./runtest
This is the main of C++
Segmentation Fault

I could not figure out the problem.  And when I call the C++ functions from the main of D everything works.  So why have I segmentation when I call the main from C++.



June 26, 2013
On Wednesday, 26 June 2013 at 20:19:07 UTC, Milvakili wrote:
> Hi, I'm a new to D and I could not find any relevant answers in the forum.
>
> I want to call functions from D-lib from c++ main.
> dlibrary
>
> import std.stdio;
>
> extern (C++) void foo(int i, int j, int k) {
>   writefln("i = %s", i);
>   writefln("j = %s", j);
>   writefln("k = %s", k);
> }
> void main(){}


Try adding this to D:

extern(C) void initialize_D() {
  import core.runtime;
  Runtime.initialize();
}



And this to C++:

> void foo(int i, int j, int k);

extern "C" void initialize_d();

> using namespace std;
>
> int main(){

    initialize_d();

>   cout << "This is the main of C++\n";
>   foo(1,3,4);
>   return 0;
> }


And you should see something better.
June 26, 2013
On Wednesday, 26 June 2013 at 20:23:35 UTC, Adam D. Ruppe wrote:
> On Wednesday, 26 June 2013 at 20:19:07 UTC, Milvakili wrote:
>> Hi, I'm a new to D and I could not find any relevant answers in the forum.
>>
>> I want to call functions from D-lib from c++ main.
>> dlibrary
>>
>> import std.stdio;
>>
>> extern (C++) void foo(int i, int j, int k) {
>>  writefln("i = %s", i);
>>  writefln("j = %s", j);
>>  writefln("k = %s", k);
>> }
>> void main(){}
>
>
> Try adding this to D:
>
> extern(C) void initialize_D() {
>   import core.runtime;
>   Runtime.initialize();
> }
>
>
>
> And this to C++:
>
>> void foo(int i, int j, int k);
>
> extern "C" void initialize_d();
>
>> using namespace std;
>>
>> int main(){
>
>     initialize_d();
>
>>  cout << "This is the main of C++\n";
>>  foo(1,3,4);
>>  return 0;
>> }
>
>
> And you should see something better.

That "magically" solves my problem.  Would you mind if I ask you to define what this initialization is all about or guide me to some tutorial related to these issues?

Thanks alot.
June 26, 2013
On Wed, 26 Jun 2013 22:32:55 +0200, Milvakili wrote:
> That "magically" solves my problem.  Would you mind if I ask you to define what this initialization is all about or guide me to some tutorial related to these issues?
> 
> Thanks alot.

The function initializes the D runtime library.  I believe the initialization must be done primarily due to the garbage collector, but there's a list of what the runtime provides in the readme here: https:// github.com/D-Programming-Language/druntime
June 26, 2013
On Wednesday, 26 June 2013 at 20:37:25 UTC, Justin Whear wrote:
> On Wed, 26 Jun 2013 22:32:55 +0200, Milvakili wrote:
>> That "magically" solves my problem.  Would you mind if I ask you to
>> define what this initialization is all about or guide me to some
>> tutorial related to these issues?
>> 
>> Thanks alot.
>
> The function initializes the D runtime library.  I believe the
> initialization must be done primarily due to the garbage collector, but
> there's a list of what the runtime provides in the readme here: https://
> github.com/D-Programming-Language/druntime

Great!
June 26, 2013
I think specifically for writefln it needs to grab module constructors from the initialization, to set up the output stream. The GC and typeinfo would be important for a longer example.

You might also want to do something similar at the end of C++'s main with Runtime.terminate().
June 27, 2013
On Wednesday, 26 June 2013 at 21:12:26 UTC, Adam D. Ruppe wrote:
> I think specifically for writefln it needs to grab module constructors from the initialization, to set up the output stream. The GC and typeinfo would be important for a longer example.
>
> You might also want to do something similar at the end of C++'s main with Runtime.terminate().

Thanks.

What about the other way around. If I linked them with dmd in that case it throws errors due to <iostream>, what should I do in that case?
June 27, 2013
On Thursday, 27 June 2013 at 00:00:23 UTC, Milvakili wrote:
> What about the other way around. If I linked them with dmd in that case it throws errors due to <iostream>, what should I do in that case?

I don't think you need to do any special C++ initialization, any needed work there is automatically inserted by the linker.

Just make sure you link with -L-lstdc++ if you're linking with dmd on Linux and the needed c++ lib should be pulled in.

Or if you want to link with g++ or ld, you'll want to link in -lphobos2 to get the D standard library.

Running dmd -v can be helpful to see exactly what is going on:

$ dmd -v test.d
< snip a lot of stuff >
gcc test25.o -o test25 -m32 -L/home/me/d/dmd2/linux/bin32/../lib32 -L/home/me/d/dmd2/linux/bin32/../lib64 -Xlinker --no-warn-search-mismatch -Xlinker --export-dynamic -l:libphobos2.a -lpthread -lm -lrt
$


Right at the end, you can see the command dmd is running to do the link. It uses gcc here, passing a bunch of libraries D will need.



But if you just let dmd do the link you can add C++ libraries with -L-l.