c - 可见性、Fortran 公共(public)变量、共享库的运行时加载

标签 c fortran visibility dlopen fortran-common-block

环境:Intel Linux、Red Hat 5。 编译器:gcc 3.4.6 (旧东西,具有严重基础设施的遗留环境,抱歉)

我有一个特定共享库的多个版本(称之为“shared_lib.so”),它源自 Fortran,其中包含一个 COMMON block 和引用该 COMMON 中的变量的各种计算。

我需要能够(从最终产品可执行文件中其他地方的 C 代码)在运行时使用 dlclose() 和 dlopen() 在这个库的版本之间切换(其中所有版本的 COMMON 内容都是相同的) .在某些情况下,相同的 COMMON 也出现在作为静态库(称为“static_lib.a”)的一部分的代码中,该库也链接到可执行文件中,并且与我的项目分开维护,但具有与我的共享图书馆。

我似乎看到 COMMON 的多个实例在可执行文件中结束,并且(更重要的是)静态库实例中的变量值与“相同”的值之间没有联系”实例中的变量来自使用 dlopen() 引入的共享库。

总而言之,我需要的是(在整个可执行文件中)加载 dlopen() 的 shared_lib.so 能够在 COMMON ABC 中设置/使用变量 XYZ,以及 static_lib.a 中的代码设置/使用 XYZ,并使其成为 XYZ 的同一个实例,或者至少使两者保持同步。这可能吗?

我对 shared_lib.so 中源代码的编译命令的形式是:

g77 –c –g –m32 -fPIC –o shared_src.o shared_src.f

我构建 shared_lib.so 的命令是这样的形式:

gcc -g -m32 -fPIC -shared -o shared_lib.so *.o

我构建可执行文件的命令是这样的形式:

gcc –g -m32 –rdynamic –o exec exec.o static_lib.a shared_lib.so –lm –ldl –lg2c

我需要从以下形式的 C 代码中做一些事情:

handle1 = dlopen ("shared_lib.so", RTLD_NOLOAD);
dlclose (handle1);
handle2 = dlopen ("shared_lib2.so", RTLD_NOW | RTLD_GLOBAL);
...

对于所需的变量,初始启动配置似乎确实可以正常运行,但后续 dlclose() 和 dlopen() 序列的结果却没有。也许潜在的问题是 dlopen() 缺少 gcc 在链接时拥有的一些智能。

最佳答案

简答

您是否/可以使用 -fPIC 重新编译可执行文件?我发现有必要使用 -fPIC 编译共享库和可执行文件,以便正确识别 COMMON block 。

长答案

我最近遇到了一个与可执行文件和 FORTRAN 共享库之间共享的 COMMON block 稍微类似的问题。但是,我使用的是 Intel 编译器,而不是 GNU 编译器。可执行文件是 C/C++FORTRAN 的混合体。

代码的现有(工作)Windows 版本通过 DLLEXPORT/DLLIMPORT ATTRIBUTE 指令共享可执行文件和 DLL 之间的公共(public) block 来工作。根据 Intel 编译器文档,Linux 无法识别这些属性指令。实际上,Linux Intel 编译器只会为这些指令生成警告。

将代码从 Windows 转换到 Linux 的主要变化是将 Windows LoadLibraryGetProcAddress 替换为 Linux 的 dlopendlsym 例程,分别使用 #ifdef 部分。共享库使用 -fpic 编译并与 -shared 链接。

虽然共享库是使用 -fpic 编译的,但可执行文件不是。当运行以这种方式编译的代码时,通过子程序调用传递给共享库的变量被正确传递,但是,COMMON block 变量设置不正确(或未初始化)。

无奈之下,我终于尝试使用 -fpic 编译器选项编译可执行文件本身,然后在共享库中正确识别了 COMMON block 。

关于c - 可见性、Fortran 公共(public)变量、共享库的运行时加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27006442/

相关文章:

c - const 指针作为函数参数的含义

oop - 使用延迟和不可重写过程和 gcc 编译器面向对象的 Fortran 中的不确定行为

Fortran 编译器 4 与 11

java - 如何使 Android ImageView 部分透明

html - 完全不可见的 html 按钮

c - 将 2 个数组排序在一起然后打印时遇到问题。 - C语言

c++ - 管道以提供文件作为 C 程序的输入

fortran - 将 4 维数组减少为 2 Fortran

c++ - 共享库名称冲突

c - 我试图将每 3 个字符(不是空格)放入一个数组中,但出现这些错误 :