Request Assistance Calling D from C++: weird visibility issue inside struct and namespace

Andrew Edwards edwards.ac at gmail.com
Wed Nov 8 06:34:27 UTC 2017


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


More information about the Digitalmars-d-learn mailing list