vra*_*en1 3 c++ linux shared-libraries dynamic-loading ldd
为什么给ldd可执行文件名时不出现动态加载的库?这是真的吗?因为我找不到什么时候给的。这可能是因为动态加载和动态链接。
请帮我解决这个问题,如果您需要任何进一步的细节,请告诉我。
输出如下。
ldd example6
linux-vdso.so.1 => (0x00007ffe63369000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f56a2676000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f56a2372000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f56a1fa9000)
/lib64/ld-linux-x86-64.so.2 (0x00007f56a287a000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f56a1ca3000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f56a1a8d000)
Run Code Online (Sandbox Code Playgroud)
我只能看到 libdl.so...但我的可执行文件,example6 依赖于 libtriangle.so,它是为某些测试而创建的。
如果您在没有 dlopen 命令的情况下访问共享库,我可以在可执行文件中找到 .so 详细信息,因为我觉得它是静态加载和动态链接。
这里可执行,main 调用共享库,libtriangle.so。共享库,triangle.so 调用另一个共享库,man.so.. man.so 调用 pthread api
Makefile 出现在最后
man.so 是使用 livingbeing.hpp,man.cpp 获得的,man.cpp 使用 pthread apis.man.so 取决于 -lpthread
triangle.so 使函数调用 man.so。triangle.so 访问共享库,man.so 使用 dlopen,dlsym 命令。
Executable,main 依赖于triangle.so。主要访问triangle.so 使用dlopen,dlsym 函数。
ldconfig 也适用于 /usr/local/lib/MYDIR 中的 .so 文件
请找到以下文件。
#ifndef LIVINGBEING_HPP
#define LIVINGBEING_HPP
#include <iostream>
using namespace std;
class livingbeing {
protected:
double side_length_;
public:
livingbeing()
: side_length_(0) {}
virtual ~livingbeing() {}
void set_length(double side_length) {
side_length_ = side_length;
}
virtual void eat() = 0;
};
typedef livingbeing* get_instance_t();
typedef void destroy_instance_t(livingbeing*);
#endif
Run Code Online (Sandbox Code Playgroud)
#include "livingbeing.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_message_function( void *ptr );
class man : public livingbeing {
public:
man()
{
cout<<"man constructor\n";
}
~man()
{
cout<<"man destructor\n";
}
virtual void eat() {
cout<<"man eating\n";
pthread_t thread1, thread2;
int iret1;
/* Create independent threads each of which will execute function */
iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) NULL);
pthread_join( thread1, NULL);
}
};
void *print_message_function( void *ptr )
{
cout<<"hello thread1 created";
}
extern "C" livingbeing * get_instance()
{
return new man;
}
extern "C" void destroy_instance(livingbeing *lb)
{
delete lb;
}
Run Code Online (Sandbox Code Playgroud)
#include "polygon.hpp"
#include "livingbeing.hpp"
#include <cmath>
#include <dlfcn.h>
//#include <iostream>
class triangle : public polygon {
public:
virtual double area() const {
// load the triangle library
void* man = dlopen("/usr/local/lib/ramu/libman.so", RTLD_LAZY);
if (!man) {
cerr << "Cannot load library: " << dlerror() << '\n';
return 1;
}
// reset errors
dlerror();
// load the symbols
get_instance_t* get_instance_man = (get_instance_t*) dlsym(man, "get_instance");
const char* dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol create: " << dlsym_error << '\n';
return 1;
}
destroy_instance_t* destroy_instance_man = (destroy_instance_t*) dlsym(man, "destroy_instance");
dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol destroy: " << dlsym_error << '\n';
return 1;
}
// create an instance of the class
livingbeing* living = get_instance_man();
// use the class
living->set_length(7);
cout << "The livingbeing is: ";
living->eat();
cout<<"\n";
// destroy the class
destroy_instance_man(living);
// unload the triangle library
dlclose(man);
return side_length_ * side_length_ * sqrt(3) / 2;
}
};
// the class factories
extern "C" polygon* create() {
return new triangle;
}
extern "C" void destroy(polygon* p) {
delete p;
}
Run Code Online (Sandbox Code Playgroud)
#include "polygon.hpp"
#include <iostream>
#include <dlfcn.h>
int main() {
using std::cout;
using std::cerr;
// load the triangle library
// void* triangle = dlopen("./triangle.so", RTLD_LAZY);
void* triangle = dlopen("/usr/local/lib/rakesh/libtriangle.so", RTLD_LAZY);
if (!triangle) {
cerr << "Cannot load library: " << dlerror() << '\n';
return 1;
}
// reset errors
dlerror();
// load the symbols
create_t* create_triangle = (create_t*) dlsym(triangle, "create");
const char* dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol create: " << dlsym_error << '\n';
return 1;
}
destroy_t* destroy_triangle = (destroy_t*) dlsym(triangle, "destroy");
dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol destroy: " << dlsym_error << '\n';
return 1;
}
// create an instance of the class
polygon* poly = create_triangle();
// use the class
poly->set_side_length(7);
cout << "The area is: " << poly->area() << '\n';
// destroy the class
destroy_triangle(poly);
// unload the triangle library
dlclose(triangle);
Run Code Online (Sandbox Code Playgroud)
example6: main.cpp triangle
$(CXX) $(CXXFLAGS) main.cpp -o example6 -L/usr/local/lib/roh -ltriangle -ldl
triangle: man triangle.cpp polygon.hpp
$(CXX) $(CXXFLAGS) -shared -fPIC triangle.cpp -o libtriangle.so
man: man.cpp livingbeing.hpp
$(CXX) $(CXXFLAGS) -shared -fPIC -o man.so man.cpp -lpthread
clean:
rm -f example6 *.so *.o
.PHONY: clean
Run Code Online (Sandbox Code Playgroud)
Executablemain不依赖于在其导入表libtriangle中包含libtriangle符号的意义。ldd不知道在运行时加载的库,dlopen因为它不运行或无论如何分析代码。它只查看符号表。请注意,即使您libtriangle在构建可执行文件时显式链接,它也无效。如果可执行文件中有一些未解析的符号位于该库中,但在main可执行文件中没有,则链接器只会真正链接库。