digitalmars.D.learn - C/C++ struct interfacing
- Oleg B (50/50) Oct 27 2013 Hello.
- =?UTF-8?B?IlLDqW15IE1vdcOremEi?= (36/86) Oct 31 2013 Below is a solution to get it to work as a C binding.
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
Oct 27 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
Oct 31 2013