digitalmars.D.learn - Request Assistance Calling D from C++: weird visibility issue inside
- Andrew Edwards (83/83) Nov 07 2017 I'm having a little bit of problem calling D code from C++ and
- Nicholas Wilson (5/8) Nov 07 2017 Try using `nm` on the C++ object to find out what it thinks the
- Andrew Edwards (12/20) Nov 07 2017 Tried it, and it works.
- evilrat (10/29) Nov 07 2017 just using fully qualified name didn't make it?
- Andrew Edwards (7/16) Nov 07 2017 Yes. That wasn't the issue
- Petar Kirov [ZombineDev] (8/27) Nov 08 2017 Walter has recently been working on improving the C++ mangling,
- Andrew Edwards (3/9) Nov 08 2017 Done: https://issues.dlang.org/show_bug.cgi?id=17975
- MGW (4/7) Nov 08 2017 The useful material.
- Andrew Edwards (2/4) Nov 08 2017 Useful indeed, thank you.
I'm having a little bit of problem calling D code from C++ and would appreciate some assistance. First, given the following C++ program wich compiles, links, and runs without any problem: ====================== // example.h SOME_API void foo(const char* str); // example.cpp #include "example.h" namespace SomeApi {} struct SomeStruct {} int main() { foo("do great things"); return 0; } void foo(const char* str) { // doing great things; } ====================== Modify example.cpp to: ====================== // example.cpp #include "example.h" namespace SomeApi {} struct SomeStruct {} void call_cpp() { foo("do great things"); return; } ====================== Then create example.d: ====================== void main() { call_cpp(); } extern (C++) void foo(const char* str) { // doing great things; } ====================== Compile and link and you have D program calling, calling C++, which in turn calls D. My problem is that I've encountered an issue where this does not work: when the function is being called from a namespace or local scope in C++, the linker cannot find the definition. For example: void SomeApi::CallFromNamespace() { foo("do great things"); } or void SomeStruct::CallFromStruct() { foo("do great things"); } In a last-ditch effort, I placed all of these definitions into dexample.d and, it compiled, but still filed to linking: extern (C) void foo(const char* str) { // doing great things; } extern (C++) void foo(const char* str) { // doing great things; } extern (C++, SOME_API) void foo(const char* str) { // doing great things; } extern (D) void foo(const char* str) { // doing great things; } extern void foo(const char* str) { // doing great things; } void foo(const char* str) { // doing great things; } =============== Linker error returned: =============== Undefined symbols for architecture x86_64: "foo()", referenced from: SomeStruct::CallFromStruct() in example.o SomeApi::CallFromNamespace() in example.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [dexample] Error 1 Using DMD v2.077.0 on macOS High Sierra -Andrew
Nov 07 2017
On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards wrote:I'm having a little bit of problem calling D code from C++ and would appreciate some assistance. First, given the following C++ program wich compiles, links, and runs without any problem:Try using `nm` on the C++ object to find out what it thinks the mangling should be. Check that against the mangling DMD produces.
Nov 07 2017
On Wednesday, 8 November 2017 at 07:06:39 UTC, Nicholas Wilson wrote:On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards wrote:Tried it, and it works. Solution: nm dexample | grep foo -> returns the __C++__mangling Use it to define the function as such: pragma(mangle, "__C++__mangling") extern (C++) void foo(const char* str) { // doing great things; } Thank you so much. -AndrewI'm having a little bit of problem calling D code from C++ and would appreciate some assistance. First, given the following C++ program wich compiles, links, and runs without any problem:Try using `nm` on the C++ object to find out what it thinks the mangling should be. Check that against the mangling DMD produces.
Nov 07 2017
On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards wrote:Modify example.cpp to: ====================== // example.cpp #include "example.h" namespace SomeApi {} struct SomeStruct {} void call_cpp() { foo("do great things"); return; } ======================Compile and link and you have D program calling, calling C++, which in turn calls D. My problem is that I've encountered an issue where this does not work: when the function is being called from a namespace or local scope in C++, the linker cannot find the definition. For example:just using fully qualified name didn't make it? void call_cpp() { ::foo("do great things"); // calling global foo return; }In a last-ditch effort, I placed all of these definitions into dexample.d and, it compiled, but still filed to linking:Are you sure you put it in a namespace in C++ too? otherwise there might be some name mangling incompatibility that probably worth filling a bug report
Nov 07 2017
On Wednesday, 8 November 2017 at 07:30:34 UTC, evilrat wrote:On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards just using fully qualified name didn't make it? void call_cpp() { ::foo("do great things"); // calling global foo return; }No, it did not.Are you sure you put it in a namespace in C++ too?Yes. That wasn't the issueotherwise there might be some name mangling incompatibility that probably worth filling a bug reportThat's the one. Thanks to the hint form, Nicholas Wilson, I was able to track it down and resolve it with a call to pragma(mangle). -Andrew
Nov 07 2017
On Wednesday, 8 November 2017 at 07:55:02 UTC, Andrew Edwards wrote:On Wednesday, 8 November 2017 at 07:30:34 UTC, evilrat wrote:Walter has recently been working on improving the C++ mangling, so be sure to test the latest dmd nightly build and if that doesn't work be sure to file bug report(s). https://github.com/dlang/dmd/pull/7250 https://github.com/dlang/dmd/pull/7259 https://github.com/dlang/dmd/pull/7272On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards just using fully qualified name didn't make it? void call_cpp() { ::foo("do great things"); // calling global foo return; }No, it did not.Are you sure you put it in a namespace in C++ too?Yes. That wasn't the issueotherwise there might be some name mangling incompatibility that probably worth filling a bug reportThat's the one. Thanks to the hint form, Nicholas Wilson, I was able to track it down and resolve it with a call to pragma(mangle). -Andrew
Nov 08 2017
On Wednesday, 8 November 2017 at 08:42:01 UTC, Petar Kirov [ZombineDev] wrote:Walter has recently been working on improving the C++ mangling, so be sure to test the latest dmd nightly build and if that doesn't work be sure to file bug report(s). https://github.com/dlang/dmd/pull/7250 https://github.com/dlang/dmd/pull/7259 https://github.com/dlang/dmd/pull/7272Done: https://issues.dlang.org/show_bug.cgi?id=17975
Nov 08 2017
On Wednesday, 8 November 2017 at 06:34:27 UTC, Andrew Edwards wrote:I'm having a little bit of problem calling D code from C++ and would appreciate some assistance. First, given the following C++ program wich compiles, links, and runs without any problem:The useful material. https://www.youtube.com/watch?v=HTgJaRRfLPk
Nov 08 2017
On Wednesday, 8 November 2017 at 15:12:05 UTC, MGW wrote:The useful material. https://www.youtube.com/watch?v=HTgJaRRfLPkUseful indeed, thank you.
Nov 08 2017