0

I have one C++ program which I want to load into my current running C++ program. Following are the snippet

File : a.cpp

    #include<bits/stdc++.h>
    using namespace std;

    void abc() { 
      cout << "This is abc" << endl;
    }

File : mainFile.cpp

    #include <bits/stdc++.h>
    #include <dlfcn.h>

    int main(int argc, char **argv) {
      system("g++ -fpic -shared -ldl -o a.so a.cpp"); 
      void *lib = dlopen("./a.so", RTLD_NOW);
       if (!lib) {
         printf("dlopen failed: %s\n", dlerror());
         return 1;
      }
      void (*f)();
      f = (void (*)()) dlsym(lib, "abc");
      if (f) {
          f();
      } else {
          printf("dlsym for f1 failed: %s\n", dlerror());
      }

      dlclose(lib);
      return 0;
    }

I am compiling with the following commands

    g++ -w mainFile.cpp -ldl -o mainFile && ./mainFile

Output:

    dlsym for f1 failed: ./a.so: undefined symbol: abc

Please help.

I am compiling in Ubuntu 16.04 with g++ version g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609

OBSERVATION What's strange is, when I have the above a.cpp file as a.c and with only stdio.h as header and also with a -fpermissive flag, the program compiles and I get the output as This is abc. I do not understand why the CPP version fails. The reason I cannot use CPP (or rather hesitate to go the .C route) is that my project requires OOPS concept and I have to use classes in the library file. The above example is only to simplify the objective. Note: I have followed the following references but none helped.

  1. Can you dynamically compile and link/load C code into a C program?
  2. undefined reference to `dlopen' since ubuntu upgrade
  3. C dlsym undefined symbol
Pradeep Mahato
  • 41
  • 2
  • 11

1 Answers1

1

In C++ names are mangled, that is, the name of the symbol in the library is not just abc. Instead it has additional characters (decoration) that describe the arguments etc. of that function. That is why you don't find the function by the name abc.

You have two options:

  1. Look up the mangled name (which may be difficult/non-portable since mangling depends on the compiler).
  2. Declare function abc() as extern "C" { void abc(); }. This requests C-linkage for the function and thus prevents name mangling.

See also the many pointers you got in the comments.

Daniel Junglas
  • 5,830
  • 1
  • 5
  • 22
  • Thank you @Daniel !! Option 1 did not seem practical for anything larger than practice exercise. I tried option 2 and it worked. – Pradeep Mahato Jan 24 '20 at 19:15