C/C++ struct interfacing
"Rémy Mouëza"
remy.moueza at gmail.com
Thu Oct 31 13:08:54 PDT 2013
Below is a solution to get it to work as a C binding.
- Your structure should not be enclosed in the `extern (C)`
block; leave it as regular D code.
- cppcall should be declared `extern (C)` in D and `extern "C"`
in C++;
- depending on your platform, you need to link to the C++
standard lib ; on my Ubuntu 12.04, I added the `-L-lstdc++` on
the dmd command line.
I already used that pattern in some binding for the RtMidi lib:
https://github.com/remy-j-a-moueza/drtmidi
dRtMidi.d defines a templated structure :
struct answer (T) {
int success;
T value;
const (char) * errMsg;
}
and so does cRtMidi.cpp :
template <typename T>
struct answer {
int success;
T value;
const char * errMsg;
};
I declared a bunch of `extern (C)` and `extern "C"` function that
pass that data arround. It works only if the T data type as the
same size in both languages.
You can check the size correspondance on this page :
http://dlang.org/interfaceToC.html
And for more tricky types, you can get some inspiration from
Jacob Carlborg dstep project, especially :
- translateType () in Type.d :
https://github.com/jacob-carlborg/dstep/blob/master/dstep/translator/Type.d
- and the static constructor of the IncludeHandler class, to get
to import the right D core module :
https://github.com/jacob-carlborg/dstep/blob/master/dstep/translator/IncludeHandler.d
On Sunday, 27 October 2013 at 12:20:49 UTC, Oleg B wrote:
> Hello.
> I want use one struct in two language.
> How to declare the same structure in different languages?
>
> D code: calling C++ function with my struct
> <code>
> extern(C++)
> {
> struct vec(size_t N, T=float)
> { // << line 6
> alias vec!(N,T) thistype;
> T[N] data;
>
> auto opBinary(string op)( in thistype rhs ) const
> {
> thistype ret;
> foreach( i; 0 .. N ) ret.data[i] = data[i] +
> rhs.data[i];
> return ret;
> }
> }
>
> void cppcall( vec!(3,float) d );
> }
>
> void main()
> {
> vec!3 a, b;
> a.data[0] = 10;
> a.data[1] = 7;
> a.data[2] = 3;
>
> b.data[0] = 13;
> b.data[1] = 9;
> b.data[2] = 4;
>
> cppcall( a + b );
> }
> </code>
>
> C++ code: use struct data
> <code>
> #include <cstdio>
>
> struct vec
> {
> float data[3];
> };
>
> void cppcall( vec d )
> {
> printf( "%f %f %f\n", d.data[0], d.data[1], d.data[2] );
> }
> </code>
>
> compilation failed with unclear error
>
> $ g++ -c ctypestest.cpp -o ctypestest.o
> $ dmd ctypestest.d ctypestest.o -ofctypestest
> ctypestest.d(6): Error: struct ctypestest.vec!(3, float).vec
> C++ static variables not supported
More information about the Digitalmars-d-learn
mailing list