Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C共享库:静态变量初始化&x2B;进程间的全局变量可见性_C_Linux_Ubuntu_Shared Libraries - Fatal编程技术网

C共享库:静态变量初始化&x2B;进程间的全局变量可见性

C共享库:静态变量初始化&x2B;进程间的全局变量可见性,c,linux,ubuntu,shared-libraries,C,Linux,Ubuntu,Shared Libraries,我想修改现有的共享库,使其根据使用共享库的应用程序使用不同的内存管理例程 (目前)将有两个系列的内存管理例程: 标准malloc、calloc等函数 malloc、calloc等的专门版本 我已经想出了一个解决这个问题的潜在方法(在一些人的帮助下)。目前仍有一些灰色地带,我希望得到一些关于我的建议的反馈 以下是我打算实施修改的方式: 用my_malloc/my_calloc等替换对malloc/calloc等的现有调用。这些新函数将调用正确分配的函数指针,而不是调用硬编码的函数名 为共享库提

我想修改现有的共享库,使其根据使用共享库的应用程序使用不同的内存管理例程

(目前)将有两个系列的内存管理例程:

  • 标准malloc、calloc等函数
  • malloc、calloc等的专门版本
我已经想出了一个解决这个问题的潜在方法(在一些人的帮助下)。目前仍有一些灰色地带,我希望得到一些关于我的建议的反馈

以下是我打算实施修改的方式:

  • 用my_malloc/my_calloc等替换对malloc/calloc等的现有调用。这些新函数将调用正确分配的函数指针,而不是调用硬编码的函数名

  • 为共享库提供一种机制来初始化my_malloc等使用的函数指针,以指向标准C内存管理例程-这允许我为依赖于此共享库的应用程序提供向后兼容性-因此它们也不必修改。在C++中,我可以通过使用静态变量初始化来实现这一点(例如)——我不确定在C.

  • 中是否可以使用相同的“模式”
  • 引入一个新的幂等函数initAPI(type)函数,该函数由需要在共享库中使用不同mem管理例程的应用程序(在启动时)调用。函数的作用是:将内存管理函数ptr分配给相应的函数

  • 显然,如果我可以限制谁可以调用initAPI()或何时调用它,那就更好了——例如,函数不应该在对库进行API调用之后调用——因为这将改变内存管理例程。因此,我想限制它在哪里被调用,由谁调用。这是一个访问问题,可以通过C++中的方法私有化来解决,但在C.

    中我不知道如何做到这一点。 < 2和3中的问题在C++中可以很好地解决,但是我受限于使用C,所以我想解决C.问题的问题。 最后,假设在如上所述的初始化过程中可以正确设置函数指针-我还有第二个问题,关于共享库中全局变量的可见性,使用共享库访问不同的进程。函数指针将作为全局变量实现(我现在不太关心线程安全性——尽管我设想在某个时候使用互斥锁包装访问)*,并且使用共享库的每个应用程序不应干扰使用共享库的另一个应用程序使用的内存管理例程

    我怀疑使用shlib的进程之间共享的是代码(而不是数据)——不过,我希望得到确认——最好是使用一个链接来支持该断言

    *注意:如果我天真地淡化了由于我上面描述的“体系结构”而可能在未来发生的线程问题,请有人提醒我


    顺便说一句,由于缺乏具体问题,我正在Linux(Ubuntu)上构建库。这篇文章很长,本可以写得更简洁,而且没有一个问号

    现在来解决您的问题:

    共享库的静态数据(您称之为“全局变量”)是每个进程的数据。一个进程中的全局变量不会干扰另一个进程中的全局变量。不需要互斥

    在C语言中,不能限制[1]谁可以调用函数。任何知道它的名字或有指向它的指针的人都可以调用它。您可以编写
    initAPI()
    ,这样,如果程序不是第一个调用的库函数,它就会明显地中止程序(使其崩溃)。你是图书馆的作者,你设定了游戏规则,你对不遵守规则的程序员没有义务


    [1] 您可以使用static声明函数,这意味着只有同一翻译单元中的代码才能按名称调用函数;任何试图获得指向它的指针的人仍然可以通过指针调用它。这些函数不是从库中“导出”的,因此这不适用于您的场景。

    -1因为缺少具体问题。这篇文章很长,本可以写得更简洁,而且没有一个问号

    现在来解决您的问题:

    共享库的静态数据(您称之为“全局变量”)是每个进程的数据。一个进程中的全局变量不会干扰另一个进程中的全局变量。不需要互斥

    在C语言中,不能限制[1]谁可以调用函数。任何知道它的名字或有指向它的指针的人都可以调用它。您可以编写
    initAPI()
    ,这样,如果程序不是第一个调用的库函数,它就会明显地中止程序(使其崩溃)。你是图书馆的作者,你设定了游戏规则,你对不遵守规则的程序员没有义务


    [1] 您可以使用static声明函数,这意味着只有同一翻译单元中的代码才能按名称调用函数;任何试图获得指向它的指针的人仍然可以通过指针调用它。这些函数不是从库中“导出”的,因此这不适用于您的场景。

    您很容易要求您的初始化函数是:

    • 从主线程调用
    • 客户可以只调用一次
    • 客户端可以通过参数提供可选的函数指针

    您很容易要求您的初始化功能是:

    • 从主线程调用
    • 客户可以只调用一次
    • 客户端可以通过参数提供可选的函数指针
      • 如果
        void __attribute__ ((constructor)) initAPI(void);
        
        #define _GNU_SOURCE
        #include <stdio.h>
        #include <stdint.h>
        #include <dlfcn.h>
        
        void * malloc(size_t size) {
           static void * (*func)(size_t) = NULL;
           void * ret;
        
           if (!func) {
              /* get reference to original (libc provided) malloc */
              func = (void *(*)(size_t)) dlsym(RTLD_NEXT, "malloc");
           }
        
           /* code to execute before calling malloc */
           ...
        
           /* call original malloc */
           ret = func(size);
        
           /* code to execute after calling malloc */
           ...
        
           return ret;
        }