2

I've been following Apple's Dynamic Library Programming Topics docs to create and use a runtime-loaded library using dlopen() / dlsym().

It seems I'm getting a failure to find the desired symbol on my Mid 2012 MacBook Air, running macOS Mojave.

Library Source Code

// adder.h

int add(int x);

and

// adder.cpp
#include "adder.h"

int add(int x) {
    return (x + 1);
}

Compiled with clang -dynamiclib adder.cpp -o libAdd.A.dylib

Main Source

// main.cpp

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

#include "adder.h"

int main() {

    void* adder_handle = dlopen("libAdd.A.dylib", RTLD_LOCAL|RTLD_LAZY);

    if (!adder_handle) {
        printf("[%s] Unable to load library: %s\n\n", __FILE__, dlerror());
        exit(EXIT_FAILURE);
    }

    while(true) {

        void* voidptr = dlsym(adder_handle, "add");
        int (*add)(int) = (int (*)(int))voidptr;

        if (!add) {
            printf("[%s] Unable to get symbol: %s\n\n", __FILE__, dlerror());
            exit(EXIT_FAILURE);
        }
        printf("%d\n", add(0));
    }

    dlclose(adder_handle);
    return 0;
}

Compiled with clang main.cpp -o main

I've also set the DYLD_LIBRARY_PATH environment variable to ensure the library can be found. Everything compiles ok.

Nevertheless, when I run the main executable, I get the error:

[main.cpp] Unable to get symbol: dlsym(0x7fb180500000, add): symbol not found 

Running nm -gC libAdd.A.dylib outputs:

0000000000000fa0 T add(int)
                 U dyld_stub_binder

Any ideas on what could be wrong, or what I need to do to debug this issue? Thanks!

Ian Taylor
  • 325
  • 5
  • 14

1 Answers1

5

C++ actually mangles the functionname which results in a different symbolname. Your are able to spot these mangled symbol names using nm -g <yourlib.dylib>

You can change this behavior by wrapping your method into

extern "C" {
   int add(int x);
}
wiomoc
  • 1,069
  • 10
  • 17
  • @BradAllred can you elaborate a bit on this? the above solution worked just fine with no changes to the main.cpp file, but I was curious why `nm -g` showed the symbol name to be `_add`. – Ian Taylor Nov 13 '18 at 20:32
  • 1
    > but I was curious why `nm -g` showed the symbol name to be `_add` this is I think some MacOS specific mangling, linux in fact does this not. It names this symbol just `add` – wiomoc Nov 13 '18 at 20:38
  • 2
    In C++ you could overload functions/methods or have the same functionname in different classes, because of that compiler has to map the function name to unique symbols, he does that using mangling. – wiomoc Nov 13 '18 at 20:49