gpt4 book ai didi

c++ - 复制动态库时 dlclose 崩溃

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:56:43 28 4
gpt4 key购买 nike

我有一个有趣的问题,我在互联网上的研究似乎没有解决。我正在尝试使用 dlfcn.h 中的函数在我的 C++ 项目中动态加载库。问题是当我尝试在运行时重新加载插件时(因为我对它们中的任何一个进行了更改),调用 dlclose() 时主程序崩溃(段错误(核心转储))。这是我重现错误的示例:

主要.cpp:

#include    <iostream>
#include <dlfcn.h>
#include <time.h>
#include "IPlugin.h"

int main( )
{
void * lib_handle;
char * error;

while( true )
{
std::cout << "Updating the .so" << std::endl;

lib_handle = dlopen( "./test1.so", RTLD_LAZY );
if ( ! lib_handle )
{
std::cerr << dlerror( ) << std::endl;
return 1;
}

create_t fn_create = ( create_t ) dlsym( lib_handle, "create" );

if ( ( error = dlerror( ) ) != NULL )
{
std::cerr << error << std::endl;
return 1;
}

IPlugin * ik = fn_create( );
ik->exec( );

destroy_t fn_destroy = ( destroy_t ) dlsym( lib_handle, "destroy" );

fn_destroy( ik );

std::cout << "Waiting 5 seconds before unloading..." << std::endl;

sleep( 5 );
dlclose( lib_handle );
}

return 0;
}

IPlugin.h:

class IPlugin
{
public:
IPlugin( ) { }
virtual ~IPlugin( ) { }
virtual void exec( ) = 0;
};

typedef IPlugin * ( * create_t )( );
typedef void ( * destroy_t )( IPlugin * );

测试1.h:

#include    <iostream>
#include "IPlugin.h"

class Test1 : public IPlugin
{
public:
Test1( );
virtual ~Test1( );

void exec( );
};

测试1.cpp:

#include "Test1.h"

Test1::Test1( ) { }

Test1::~Test1( ) { }

void Test1::exec( )
{
std::cout << "void Test1::exec( )" << std::endl;
}

extern "C"
IPlugin * create( )
{
return new Test1( );
}

extern "C"
void destroy( IPlugin * plugin )
{
if( plugin != NULL )
{
delete plugin;
}
}

编译:

g++ main.cpp -o main -ldl
g++ -shared -fPIC Test1.cpp -o plugin/test1.so

例如,当我在 Test1::exec 方法上更改某些内容(更改要打印的字符串或注释该行)并且当主程序休眠时我将新的 test1.so 复制到主运行目录(cp ).如果我使用移动命令 (mv),不会发生错误。使用 cp 或 mv 有什么区别?有什么方法可以解决这个问题或使用 cp 来解决这个问题吗?

我正在使用带有 g++ (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4) 的 Fedora 14。

提前致谢。

最佳答案

与本题相关的cpmv的区别如下:

  1. cp 打开目标文件并将新内容写入其中。因此,它用新内容替换旧内容
  2. mv 不触及原始文件的内容。相反,它使目录入口指向新文件。

事实证明这很重要。当应用程序运行时,操作系统会保持打开可执行文件和共享对象的句柄。当它需要查阅这些文件之一时,它会使用相关的句柄来访问文件的内容。

  1. 如果您使用过 cp,内容现在已经损坏,所以任何事情都可能发生(很可能会出现段错误)。
  2. 如果您使用过 mv,打开的文件句柄仍然指的是原始文件,即使不再有目录条目,它仍然存在于磁盘上。

如果您使用mv 来替换共享对象,您应该能够dlclose 旧的和dlopen 新的.但是,这不是我做过或不会推荐的事情。

关于c++ - 复制动态库时 dlclose 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7730955/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com