1

所以,我有一个我正在尝试运行的示例。

头文件.h

extern "C" {
        void registerfunc();
};

主文件

#include "header.h"
#include <dlfcn.h>
#include <iostream>

using namespace std;

typedef void (*register_func)();

void registerfunc() {
    cout << "register func has been called" << endl;
}

int main() {
    void* lib_handle = dlopen("./test/test.so", RTLD_NOW | RTLD_GLOBAL);

    if(lib_handle == NULL){
            cout << "no such lib:" << dlerror() <<endl;
            return 0;
    }

    register_func reg = (register_func)dlsym(lib_handle, "test");

    if(reg == NULL){
            cout << "Cannot load symbol" <<  dlerror() << endl;;
    } else {
            reg();
    }
    return 0;
}

它是用以下makefile编译的

all:
    g++ main.cpp -ldl

然后,我想使用我自己的 registerfunc ,它的编写方式如下:

主.h:

extern "C"
{
    void test();
};

主文件

#include "main.h"
#include "../header.h"

void test() {
    registerfunc();
}

生成文件:

all:
    g++ main.cpp -fPIC -shared -o test.so

当我以这种方式编译它并运行 a.out (第一个 main 的输出)时,我得到:

 no such lib: ./test/test.so: undefined symbol: registerfunc

但是,如果我使用以下命令编译 a.out 和 test.so:

a.out -> g++ -g -fPIC -shared main.cpp -ldl
test.so -> g++ -g main.cpp -fPIC -shared -o test.so ../a.out

然后我通过以下回溯(gdb -ex run a.out)遇到分段错误:

0x0000000000000001 in ?? ()

这让我有点难过,至于如何让 test.so 调用由它的被调用者定义的东西。能否请你帮忙?

4

1 回答 1

1

您在这里至少有三个不同的问题:

  • 较小的一个是您有两个名为main.cpp的文件,并且不完全清楚哪个命令引用了您的问题中的哪个文件。

  • 更大的问题是您希望test.so绑定到registerfunca.out,但除非某些参与链接的共享库引用该函数,或者您链接到(导出所有函数) ,否则该函数不会从中导出。这是真正的解决方案。a.out -Wl,--export-dynamic

    a.out您可以使用以下命令查看从您导出的函数:

    nm -D a.out | grep ' T '

  • 最后,当你这样做时:

    a.out -> g++ -g -fPIC -shared main.cpp -ldl

    您实际上是在创建一个共享库(名为a.out),而不是可执行文件。像运行可执行文件一样运行这样的共享库会导致您观察到的崩溃。

于 2015-03-16T02:05:13.863 回答