我创建了一个共享库,在其中我定义了一个类Foo。在类Foo中,有一个名为sayHi()的函数。我的问题是,一旦我创建了一个Foo对象foo,我怎么能调用它的sayHi()。我把我的代码放在这里。
mylib.h
#ifndef FUNTEST_MYLIB_H
#define FUNTEST_MYLIB_H
class Foo {
public:
int id = 0;
void sayHi();
};
#endif //FUNTEST_MYLIB_H
mylib.cpp
#include <iostream>
#include "mylib.h"
using namespace std;
void Foo::sayHi()
{
cout << "Implemented by lib" << endl;
cout << "id is: " << id << endl;
}
Foo* create()
{
return new Foo();
}
然后我使用以下命令编译共享库:
g++ -c -std=gnu++11 -fPIC mylib.cpp
g++ -shared -fPIC -o mylib.so mylib.o
在客户端,我写了两个文件:
mylib2.cpp
#include <iostream>
#include "mylib.h"
using namespace std;
void Foo::sayHi() {
cout << "Implemented by caller" << endl;
cout << "id is: " << id << endl;
}
的main.cpp
#include <iostream>
#include <dlfcn.h>
#include "mylib.h"
using namespace std;
Foo* (*create)();
void (*sayHi)();
int main() {
void* lib = dlopen("./mylib.so", RTLD_LAZY);
create = (Foo* (*)())dlsym(lib, "_Z6createv");
sayHi = (void (*)())dlsym(lib, "_ZN3Foo5sayHiEv");
Foo* foo = create();
sayHi();
foo->sayHi();
foo->id = 100;
cout << "Set id to " << foo->id << endl;
/*
*
* how can I make the follow statement 'sayHi();'
* output the following content:
* Implemented by lib
* id is: 100
*/
sayHi(); // line 29, FIXME
foo->sayHi();
return 0;
}
使用以下命令编译客户端:
g++ -std=gnu++11 main.cpp mylib.h mylib2.cpp -ldl
最后运行客户端: ./a.out
输出是:
Implemented by lib
id is: 0
Implemented by caller
id is: 0
Set id to 100
Implemented by lib
id is: -1407102376 // FIXME
Implemented by caller
id is: 100
如何制作声明'sayHi();'在第29行输出以下内容:
Implemented by lib
id is: 100
我知道如果我直接调用sayHi()函数,没有foo对象,输出就会出错。但我该如何解决呢?
答案 0 :(得分:0)
main.cpp中sayHi
全局变量的声明是错误的。您将其声明为函数指针。但是,由于它指向成员函数,因此它需要是成员函数指针。
void (Foo::*sayHi)();
然后当你调用它时,你需要一个Foo
对象:
(foo->*sayHi)();
或者,如果您使用sayHi
方法virtual
,则根本不需要为其加载符号,因为vtable会有效地处理该符号。