gpt4 book ai didi

在 C 中跨多个文件编译全局变量以创建共享库

转载 作者:行者123 更新时间:2023-11-30 17:44:29 24 4
gpt4 key购买 nike

我正在构建一个由 C 构建的共享对象 (.so) 文件,以便从 R 使用。我在链接/编译该对象与所有源代码、测试代码和 header 时遇到问题文件。

这个.so文件将使用R中的dyn.load()加载并调用相应的函数。

这是文件的结构:

C_header_file1.h // some support functions
C_src_file1.h // some source code for support functions
C_header_file2.h // some other support functions
C_src_file2.h // some source code for support functions
C_header_testfunctions.h // testing functions that are called from R for testing
C_src_testfunctions.c // source code for test functions
C_file_with_main_calling_functions.c // main src file which takes functions from header files (not test header file) to do stuff
C_file_with_main_extern_vars.h // has extern global variables

C_file_with_main_calling_functions.c 文件有一组全局变量(随机数生成器细节),可以通过 C_file_with_main_calling_functions.c 访问(当主函数被调用时) R 中的用户)和 C_src_testfunctions.c(当用户在测试阶段从 R 中调用测试函数时)。

C_file_with_main_extern_vars.h 看起来像:

// random number generation set up
extern const gsl_rng *gBaseRand; // global rand number generator
extern unsigned long randSeed;
extern const double lowest_double = -GSL_DBL_MAX;
extern const double highest_double = GSL_DBL_MAX;
extern FILE *fp = NULL;

C_file_with_main_calling_functions.cC_src_testfunctions.c 都有 #include "C_file_with_main_extern_vars.h"

如何创建共享对象?它给了我以下错误:

R CMD SHLIB C_file_with_main_calling_functions.c ./../test/C_src_testfunctions.c ./../src/src_file1.c ./../src/src_file2.c ./../src/src_file3.c ./../src/src_file6.c ./../src/src_file5.c -lgsl -lgslcblas
gcc -std=gnu99 -I/usr/local/R.framework/Resources/include -DNDEBUG -I/sw/include -I/usr/local/include -fPIC -g -O2 -c C_file_with_main_calling_functions.c -o C_file_with_main_calling_functions.o
In file included from C_file_with_main_calling_functions.c:35:
/mydir/C/include/C_file_with_main_calling_functions.h:15: warning: 'lowest_double' initialized and declared 'extern'
/mydir/C/include/C_file_with_main_calling_functions.h:16: warning: 'highest_double' initialized and declared 'extern'
/mydir/C/include/C_file_with_main_calling_functions.h:17: warning: 'fp' initialized and declared 'extern'
C_file_with_main_calling_functions.c: In function 'func2':
C_file_with_main_calling_functions.c:54: warning: implicit declaration of function 'func1'
C_file_with_main_calling_functions.c: At top level:
C_file_with_main_calling_functions.c:61: warning: conflicting types for 'func1'
C_file_with_main_calling_functions.c:54: warning: previous implicit declaration of 'func1' was here
C_file_with_main_calling_functions.c: In function 'C_file_with_main_calling_functionsC':
C_file_with_main_calling_functions.c:207: warning: passing argument 1 of 'func2' from incompatible pointer type
C_file_with_main_calling_functions.c:271: warning: passing argument 1 of 'gsl_rng_free' discards qualifiers from pointer target type
gcc -std=gnu99 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/sw/lib -L/usr/local/lib -o C_file_with_main_calling_functions.so C_file_with_main_calling_functions.o ./../test/C_src_testfunctions.o ./../src/src_file1.o ./../src/src_file2.o ./../src/src_file3.o ./../src/src_file6.o ./../src/src_file5.o -lgsl -lgslcblas -F/usr/local/R.framework/.. -framework R -lintl -Wl,-framework -Wl,CoreFoundation
duplicate symbol _fp in:
C_file_with_main_calling_functions.o
./../test/C_src_testfunctions.o
duplicate symbol _lowest_double in:
C_file_with_main_calling_functions.o
./../test/C_src_testfunctions.o
duplicate symbol _highest_double in:
C_file_with_main_calling_functions.o
./../test/C_src_testfunctions.o
ld: 3 duplicate symbols for architecture x86_64
collect2: ld returned 1 exit status
make: *** [C_file_with_main_calling_functions.so] Error 1

我也不想要两个单独的共享对象(一个用于测试,一个供用户使用)(我已经尝试过并且有效)。

最佳答案

在C语言中初始化就是定义。

让我们考虑简单的示例:decl.h 文件包含单个声明

#ifdef CORR
extern int i;
#else
extern int i = 5;
#endif

decl.c 文件包含定义:

#include "decl.h"
int i = 5;
int foo() { return i; }

现在使用 gcc -DCORR decl.c -c 进行编译,您将不会发现任何问题,但如果您尝试在 extern 声明中使用初始化进行编译,您将出现多个定义错误。

因此您的头文件只需包含声明,并且可能如下所示:

extern const gsl_rng *gBaseRand;
extern unsigned long randSeed;
extern const double lowest_double;
extern const double highest_double;
extern FILE *fp;

在任何 C 文件中,例如 C_file_with_main_calling_functions.c,您可以放置​​一些定义:

const gsl_rng *gBaseRand;       // global rand number generator
unsigned long randSeed;
const double lowest_double = -GSL_DBL_MAX;
const double highest_double = GSL_DBL_MAX;
FILE *fp = NULL;

然后一切都应该编译和链接,没有错误。

关于在 C 中跨多个文件编译全局变量以创建共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19973313/

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