编译具有多个 main() 的 C 文件



我是C语言的初学者,我有一个关于编译C文件的问题。我需要为带有main()的应用程序编写一个通用包代码(common.c),以解析配置文件并设置一些变量。我需要将此文件导入另一个文件,例如使用 #include(?) 的 local.c,并再次在此处使用 main() 并在 common.c 中调用某些函数。现在,当我使用 gcc 编译这些文件时,我收到一个错误:main() 的多个声明。

有没有办法先编译和运行common.c,然后在local.c中使用此文件设置的变量?我应该使用哪些生成文件规则?

普通.h

#ifndef __DAEMON_COMMON__
#define __DAEMON_COMMON__
extern int a;
extern const char* type;


int add(int a, int b);
void print(int n);

#endif

通用.c

int a = -1;
int main(int argc, char *argv[]){
// parse file in arg and initialize variables declared as extern

a = 10;
}

int add(int a, int b){
return a + b;
}

void print(int n){
printf("%d",n);
}

common.c 和 common.h 位于 common.c 中,

使用
#include <common.h>

本地.c

#include <common.h>

int main(){
add(5,10);
print(a);  // I want to access 'a' initialized in common.c here

return 0;
}

如注释中所述和编译器报告的那样,您不能有多个main函数。您必须从编译中排除除单个main函数之外的所有函数,或者重命名其他函数并自行调用它(它们)。

common.cmain函数的目的似乎是变量的初始化。您可以通过不同的方式执行此操作。


使用问题中的示例,您可以简单地执行正确的静态初始化,而无需使用函数。

普通.h

#ifndef __DAEMON_COMMON__
#define __DAEMON_COMMON__
extern int a;
extern const char* type;
int add(int a, int b);
void print(int n);
#endif

通用.c

/* add this include here to allow the compiler to check your implementation against the declaration */
#include "common.h"
/* correct initialization here instead of a main() function */
int a = 10;
int add(int a, int b){
return a + b;
}
void print(int n){
printf("%d",n);
}

本地.c

/* #include <...> is normally used for system include files, #include "..." for files from your project */
#include "common.h"

int main(){
add(5,10); /* useless call because result is unused and no side effects in function */
print(a);  // I want to access 'a' initialized in common.c here
return 0;
}

假设在您的实际用例中,所需的初始化更复杂,并且旨在依赖于命令行参数,则可以使用初始化函数以不同的方式解决此问题。

请注意,以下代码中使用OPTION1OPTION3进行条件编译的不同选项用于在单个源代码中演示不同的解决方案。与其以这种方式实现它,不如简单地选择适合您的要求或最喜欢的选项。

普通.h

#ifndef __DAEMON_COMMON__
#define __DAEMON_COMMON__
extern int a;
extern const char* type;
int add(int a, int b);
void print(int n);
/* option 1: main() processes command line args and calculates value */
void common_init_a(int value);
/* option 2: main() passes command line args for processing in common.c */
void common_init(int argc, char **argv);
#endif

通用.c

#include "common.h"
int a = -1;
int add(int a, int b){
return a + b;
}
void print(int n){
printf("%d",n);
}
/* option 1 */
void common_init_a(int value) {
a = value;
}
/* option 2 */
void common_init(int argc, char **argv) {
/* process argc and argv to calculate the value for a */
a = 10; /* In reality this is a calculated value, not a constant */
}

本地.c

#include "common.h"
int main(int argc, char **argv){
/* run the initialization of the common module */
#ifdef OPTION1
/* option 1 */
/* process argc and argv to calculate the value for a */
common_init_a(10); /* In reality this is a calculated value, not a constant */
#else
/* option 2 */
common_init(argc, argv) {
#endif
add(5,10);
print(a);  // I want to access 'a' initialized in common.c here
return 0;
}

此解决方案的缺点是初始化必须由使用common模块的任何程序显式调用。


您可以通过多种方式改进这一点。您可以将"已初始化"状态保存在common.c中,并使您的函数返回错误,以防之前未初始化。如果初始化不依赖于输入值,则函数可以在必要时隐式运行初始化。

通用.c

#include "common.h"
/* option 3, see below */
static void init_internal(void);
int a = -1;
static int initialized = 0;
int add(int a, int b){
if(!initialized) {
#ifndef OPTION3
/* option 1 or 2 */
/* handle error */
return ERROR_INDICATION; /* not very useful for this "add" function, but maybe in the real use case */
#else
/* option 3: implicit initialization as required */
init_internal();
#endif   
}
return a + b;
}
void print(int n){
printf("%d",n);
}
/* option 1 */
void common_init_a(int value) {
a = value;
initialized = 1;
}
/* option 2 */
void common_init(int argc, char **argv) {
/* process argc and argv to calculate the value for a */
a = 10; /* In reality this is a calculated value, not a constant */
initialized = 1;
}
/* option 3: internal initialization without input values */
static void init_internal(void) {
a = 10;
initialized = 1;
}

本地.c

#include "common.h"
int main(int argc, char **argv){
/* With option 3, initialization is implicit in every function that requires it. */
#ifndef OPTION3
/* run the initialization of the common_module */
# ifdef OPTION1
/* option 1 */
/* process argc and argv to calculate the value for a */
common_init_a(10); /* In reality this is a calculated value, not a constant */
# else
/* option 2 */
common_init(argc, argv) {
# endif
#endif
add(5,10);
print(a);  // I want to access 'a' initialized in common.c here
return 0;
}

编辑作为对评论的回复

这是嵌入式软件项目的一部分 [...]common.c中的main()解析文件并初始化变量,在我的local.c中,我有一个main(),我在其中调用函数并使用在common.c中声明和定义的变量common.h

您必须重命名其中一个函数。

与上面显示的解决方案不同,local.c的函数main()调用common_init()或类似的函数,您可以从common.c中调用函数,相反,并要求特定的(本地)应用程序代码具有名为local_main()的函数(或由函数调用在common.c中定义的任何名称)具有特定的签名和行为,该签名和行为将从common.c中的main()调用。

例:

普通.h

#ifndef __DAEMON_COMMON__
#define __DAEMON_COMMON__
extern int a;
extern const char* type;


int add(int a, int b);
void print(int n);
/* declaration of required function in local.c */
int local_main(void);

#endif

通用.c

#include "common.h"
int a = -1;
int main(int argc, char *argv[]){
// parse file in arg and initialize variables declared as extern

a = 10;
return local_main();
}

int add(int a, int b){
return a + b;
}

void print(int n){
printf("%d",n);
}

本地.c

#include "common.h"

int local_main(){
add(5,10);
print(a);  // I want to access 'a' initialized in common.c here

return 0;
}

相关内容

  • 没有找到相关文章

最新更新