Proof of Concept: Binding to and extending C++ objects via a metric fuckton of templates
downs
default_357-line at yahoo.de
Wed Dec 9 14:37:09 PST 2009
I've just committed a module to tools (tools.cpp, http://dsource.org/projects/scrapple/Trunk/tools/tools/cpp.d ) that should enable linking and using any C++ library with D programs without creating a C wrapper for it.
The code has been tested with a simple multiple-inheritance sample: http://paste.dprogramming.com/dpv8hpjp
The D code to bind to this is http://paste.dprogramming.com/dphlv1ot . It requires a symlink to the tools folder in its directory.
Caveats:
- D1
- Only works on g++4's "newapi" layout and mangling (but should be reasonably portable).
- Diamond pattern is untested and unsupported.
- Class protection is completely unsupported - public only.
- RTTI must be generated manually (normally the compiler would do this). See the D half of the sample.
- Dynamic casting from and to generated classes is not implemented.
- The C++ code that does this is long and full of special cases, so
- For the example, I ended up hardcoding a manual translation between A and B.
- If you need dynamic casting, I recommend hardcoding the required paths based on classinfo pointer comparisons.
- The C++ DSL parser is not very tested. Occasional bugs may occur.
- When building with LDC, fixup_vtable() needs to be called for every newly created C++ class object.
- This is because LDC does not yet support initialization from global variable addresses.
Building the sample is a two-step process:
g++ test.cpp -c -g -o test.o
gdc -J. cpp_demo.d tools/cpp.d tools/base.d tools/smart_import.d tools/ctfe.d tools/compat.d tools/text.d tools/tests.d tools/log.d test.o \
-o cpptest -lstdc++ -L /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/ -g # adapt library path as appropriate
Writing this also gave us what I believe to be a fair contender to Most Horrifying Statement of D Ever Written:
fndefs ~= `mixin("extern(C) `~t~` "~`~mname~`~"`~fnparams~`; ");`~'\n'~
`mixin("`~fn~`("~refToParamList("Params!(typeof(&"~`~mname~`~"))", isRef!(typeof(mixin("&"~`~mname~`))))~") {
return "~`~mname~`~"("~refToValueList(isRef!(typeof(mixin("&"~`~mname~`))))~");
}
"); `;
--downs
More information about the Digitalmars-d
mailing list