How to interface with C++ code or dll?

Mike Parker via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jan 11 18:34:27 PST 2015


On Sunday, 11 January 2015 at 12:56:40 UTC, Suliman wrote:

> I had read about using C++ libs from D, and understood that 
> there is 2 ways:
> 1. Make binding - convert .H to .d (I still do not fully 
> understand what is it)
> 2. Use directly C++ lib (.dll)

No, there are not two ways. There is one way. In order to use any 
library from C or C++, you *have* to create a binding. The 
binding tells the compiler the function signatures and types that 
are available to be used. It allows you to compile your code 
without error. Then, the C or C++ library can be linked with the 
final executable just like a D library, or (in the case of shared 
libraries) loaded at runtime (as Derelict does) with system calls.


>
> I decided to start from simple example 
> http://www.gdal.org/warptut.html
>
> For compiling it's need #include "gdalwarper.h", so I maked 
> gdalwarper.d with tool htod.
> I know that it's not recommended for usage more, but other 
> tools look too complex for me (I even do not understand how to 
> sun them on Windows).
>
> After I had add import gdalwarper.d to my test project. But 
> during compilation it's asked me about other d files, that I 
> included one ny other in App.d file. In the result I got error 
> that:
> "source\cpl_port.d(147): Error: module ctype is in file 
> 'std\c\ctype.d' which can not be read"

You've imported std.c.ctype, which doesn't exist. You need to 
import core.stdc.ctype instead. All of the C stuff is in 
core.stdc in DRuntime.

>
> I have got a question. Files that I include is only header 
> files. They do not include any code. How App would run? I 
> should specify C++ source location or what?

Imports are only used at compile time to determine which types 
and functions are available to use. We don't need the code for 
the C or C++ stuff because everything is already compiled in the 
library that you are linking to or loading. Even in D, you don't 
need the code for modules you import -- only their function 
signatures and type declarations. D is designed such that you 
don't need to separate the interface from the implementation, but 
you can if you want to (that's what .di files are for).

To be clear, let's say you have module a.d and another module 
b.d. Module a has a function sayHello. You compile module a and 
the code for say hello, which prints hello to the screen, is 
translated and saved in a library. Later, you compile b.d. Since 
module b imports a, then the compiler has to load a into memory 
and parse the signature for the function sayHello -- but it 
doesn't *need* the code for say hello. All it needs is this part:

void sayHello( string str );

It doesn't care what the implementation of the function looks 
like, because now it isn't compiling a.d, it's compiling b.d. It 
only needs to know how to call the function and what it returns 
so it can throw an error if b.d calls sayHello with an int or a 
float or anything that isn't a string. Then, when the executable 
is generated, the linker will match up the call to sayHello in b 
with the implementation of sayHello in a.

There are some exceptions to this. You need the implementation of 
templates and anything you want to use at compile time, but for 
code that is runtime only you don't.

>
> =========
>
> Then I decided to look how to use ready dll. As far as I know D 
> have directive pragma(), that allow to import any lib.
> Also afaik that it support inly import of dll in format of lib. 
> Am I right?

No. This is not a feature of D. D has a "lib" pragma that allows 
you to link to a library without passing the library on the 
command line. THat is:

pragma( lib, "MyLib.lib" );

This will cause the compiler to automatically link MyLib.lib to 
your app. It's the same as passing MyLib.lib on the command line. 
The compiler still needs to know the path where the library can 
be found.

However, this does *not* allow you to automatically use any 
library in D without importing the library's source modules. So 
for a C or C++ library, you still need a binding to import.




More information about the Digitalmars-d-learn mailing list