Jump to page: 1 2
Thread overview
Proof of Concept: Binding to and extending C++ objects via a metric fuckton of templates
Dec 09, 2009
downs
Dec 09, 2009
BCS
Dec 10, 2009
downs
Dec 10, 2009
retard
Dec 10, 2009
downs
Dec 10, 2009
BCS
Dec 10, 2009
Nick Sabalausky
Dec 11, 2009
Bernard Helyer
Re: Proof of Concept: Binding to and extending C++ objects via a metric
Dec 09, 2009
g
Dec 10, 2009
g
Dec 10, 2009
downs
Dec 10, 2009
dsimcha
Dec 10, 2009
downs
Dec 10, 2009
Don
Dec 11, 2009
Tim Matthews
Dec 12, 2009
downs
Dec 12, 2009
Denis Koroskin
Dec 13, 2009
BCS
December 09, 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
December 09, 2009
please tell me the subject is a freudian slip (or just a typo).


December 09, 2009
omg
December 10, 2009
downs Wrote:

> 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

if you have problems seeing the first link: http://dsource.org/projects/scrapple/browser/trunk/tools/tools/cpp.d
December 10, 2009
BCS wrote:
> please tell me the subject is a freudian slip (or just a typo).
> 
> 
Considering the amount of abuse me and the compiler put each other through in the course of writing this, including such gems as incorrect tuple lengths, incorrect tuple slices, endless errors without line numbers, spurious template instantiation errors with nonsensical parameters, and at least one case where T[0] evaluated to T, necessitating the workaround Tuple!(T[0])[0], it felt appropriate.
December 10, 2009
g wrote:
> downs Wrote:
> 
>> 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
> 
> if you have problems seeing the first link: http://dsource.org/projects/scrapple/browser/trunk/tools/tools/cpp.d

Oops. Sorry for that. (Never a post without an error!)
December 10, 2009
== Quote from downs (default_357-line@yahoo.de)'s article
> 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

Awesome!  One quick question.  This may be a stupid question, as I don't understand at all yet how this works:  Can you instantiate C++ templates with this thing, or does it work only w/ non-templated C++ code?
December 10, 2009
dsimcha wrote:
> == Quote from downs (default_357-line@yahoo.de)'s article
>> 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
> 
> Awesome!  One quick question.  This may be a stupid question, as I don't understand at all yet how this works:  Can you instantiate C++ templates with this thing, or does it work only w/ non-templated C++ code?

Nontemplates only. C++ templates require a C++ compiler.

If you instantiate them in C++ code, you can then use them in D code, but I haven't looked into how the mangling would look like for this.
December 10, 2009
Thu, 10 Dec 2009 01:01:34 +0100, downs wrote:

> including such gems as incorrect
> tuple lengths, incorrect tuple slices, endless errors without line
> numbers, spurious template instantiation errors with nonsensical
> parameters, and at least one case where T[0] evaluated to T,
> necessitating the workaround Tuple!(T[0])[0], it felt appropriate.

Why are these needed? Because of compiler bugs?
December 10, 2009
retard wrote:
> Thu, 10 Dec 2009 01:01:34 +0100, downs wrote:
> 
>> including such gems as incorrect
>> tuple lengths, incorrect tuple slices, endless errors without line
>> numbers, spurious template instantiation errors with nonsensical
>> parameters, and at least one case where T[0] evaluated to T,
>> necessitating the workaround Tuple!(T[0])[0], it felt appropriate.
> 
> Why are these needed? Because of compiler bugs?

Apparently, in certain very specific corner cases, my version of GDC believes that when I say "T[0]", I really mean "T". In that case, "Tuple!(T[0])[0]" is like saying "really very the first element". :)
« First   ‹ Prev
1 2