【问题标题】:is it possible to load a shared library on a shared memory?是否可以在共享内存上加载共享库?
【发布时间】:2010-05-15 08:51:55
【问题描述】:

我有一个用 C 编写的服务器和一个客户端。我尝试在服务器中加载一个共享库,然后将库函数指针传递给客户端。这样我就可以更改库而无需编译客户端。

因为每个进程都有自己独立的内存空间,我想知道是否可以在共享内存上加载共享库,在客户端传递函数指针和映射共享内存,然后让客户端执行代码服务器加载的库。

【问题讨论】:

  • 服务器和客户端是否在同一台机器上运行?
  • 是的,服务器和客户端在同一台机器上运行。服务器读取一个 xml 文件,并根据 xml 查询返回库函数名称。客户端读取函数名并尝试获取库函数指针来执行它们。
  • 我不想将库与客户端链接,因为我希望能够更改功能而无需编译客户端。而且我不希望(如果可能的话)在客户端上 dlopen 库,因为客户端将被调用多次。

标签: c memory linker shared


【解决方案1】:

根据定义,共享库是共享的,因此两个进程将使用相同的物理内存来存储库的代码段。因此,您可以将库和函数的名称从服务器传递到客户端,而不是编造一些狡猾的方案,客户端将使用dlopen() + dlsym() 获取函数地址。

请注意,在这种情况下,将有两个数据段副本(如果库有一些全局或静态变量),例如如果服务器在库函数中设置了一些static 变量,它的值对于客户端不会改变。

【讨论】:

  • 是的,你是对的。所以,我在服务器上打开库,将函数名传递给客户端。从客户端,我在同名库(已经打开)上使用 dlopen,并使用 dlsym 来获取函数指针以执行其代码。但是根据 man dlopen 的说法,这应该在客户端和服务器上给我相同的句柄,我得到:服务器为 0x970b0d0,客户端为 0x89d2a38。这是否意味着库已经加载了两次?
  • 您获得了属于服务器和客户端进程地址空间的虚拟地址,但它们应该映射到相同的物理地址。
  • @qrdl:有没有办法验证这一点?
【解决方案2】:

如果操作系统没有将共享内存也可执行称为安全问题(它可能应该),那么您可能会这样做。

但你不需要。而且,您不应该将指针传递给其他进程。相反,在您的协议中给出函数名称或代码点。共享库机制意味着内存中只有一个库副本,除非操作系统出于某种原因决定不共享。如果操作系统决定不共享,可能的原因通常会导致您的指针传递技巧也失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 2021-09-24
    • 2019-04-17
    • 2010-09-21
    • 1970-01-01
    相关资源
    最近更新 更多