【问题标题】:C - Libraries with the same function and variable namesC - 具有相同函数和变量名称的库
【发布时间】:2021-05-01 18:59:31
【问题描述】:

我想包含两个我从源代码构建的库。

更详细地说:这些库大体上是相同的,除了一些不同的参数并由 a 设置

#define Mode *X*

X 描述了模式并描述了要使用的参数集。例如

对于 x = 2 我想使用

#define N 3
#define Q 4

在一个库中,我的 x 是例如 2,而在另一个 3 中,例如 N 4 和 Q 6。

此外,这些库包含相同的函数,它们根据设置的模式运行略有不同。

我需要同时包含它们并保持选项打开以使用这两个参数集。

任何想法如何正确和干净地实现这一点?整个事情只取决于模式,不幸的是,重命名所有包含的函数和变量是没有选择的。但是我可以访问源代码并且可以进行一些更改。

我尝试构建库并将它们包含在我的主程序中,但显然我有很多命名冲突,并且链接器找到的第一个定义设置为正确。

另一个问题是所有头文件都以e.g.开头

 #ifndef CONFIG
 #define CONFIG

这是标准的,可以,但我有两次所有文件,所以只有链接器包含的第一个标头看到它尚未定义,第二个标头已定义,因此编译器不执行以下代码.

有人知道如何解决这个优雅的问题吗?

我听说过一些关于命名空间的事情,但我不确定这是否适用于 C 以及正确的方法。

BR

【问题讨论】:

  • 关于包含头文件的问题,您可以将 CONFIG 的名称更改为每个头文件更具描述性的名称。例如,如果头文件位于不同的目录中,您可以将目录名称添加到常量名称
  • 为什么不能用#if MODE==2 #define N 3 ...之类的?
  • 我这样做了,但是如果我构建库并链接它们,您仍然会有冲突的类型,因为名称仍然相同

标签: c include


【解决方案1】:

您可能不得不在运行时加载外部库。

如果您使用的是 Linux,您可以使用 dlopen 在运行时打开一个库,然后使用 dlsym 提取您想要使用的每个变量和函数。

您可以创建一个结构,该结构将包含指向库实例的变量和函数的指针,然后为库的每个变体填充该结构的副本。从那里,您将使用来自适当结构实例的函数指针来调用特定的库函数。

例如,假设您有以下库文件:

x2.c:

#include <stdio.h>

void foo()
{
    printf("in x2 foo\n");
}

x3.c

#include <stdio.h>

void foo()
{
    printf("in x3 foo\n");
}

这些分别编译成libx2.so和libx3.so。然后你的主要来源可以这样做:

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

struct lib {
    void (*foo)(void);
};

int main(void)
{
    struct lib lib2;
    struct lib lib3;

    void *l2 = dlopen("./libx2.so", RTLD_NOW);
    if (!l2) {
        printf("dlopen x2 failed: %s\n", dlerror());
        exit(1);
    }
    void *l3 = dlopen("./libx3.so", RTLD_NOW);
    if (!l3) {
        printf("dlopen x3 failed: %s\n", dlerror());
        exit(1);
    }

    lib2.foo = dlsym(l2, "foo");
    lib3.foo = dlsym(l3, "foo");

    lib2.foo();
    lib3.foo();

    dlclose(l2);
    dlclose(l3);
    return 0;
}

输出:

in x2 foo
in x3 foo

【讨论】:

  • 谢谢,这绝对是一种方法,但出于我的目的,每次我需要它们时都动态地打开库。还有一种方法可以使一些变量或常量对外部“不可见”吗?这样,除了一些功能,库是一个封闭的系统,你可以避免碰撞?
  • @LykVanDyk 您不会在每次调用函数时都打开库。您将在程序开始时执行一次以填充一组或多组函数(和数据)指针。然后,当您需要调用一个函数时,您可以使用之前存储的指针之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2011-04-14
  • 2013-06-16
  • 1970-01-01
  • 1970-01-01
  • 2021-08-26
  • 1970-01-01
相关资源
最近更新 更多