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

Reply via email to