繁体   English   中英

在同一头文件中声明功能指针之后使用extern的优点

[英]Advantages of using extern after the declaration of fucntion pointer in the same header file

在下面的代码中,可以解释为什么在函数指针的声明之后立即使用extern。

myfuncs.h

typedef void    (*initMyfuncs_t)(Init_t*, CallBacks_t *,result_t*);
extern initMyfuncs_t _initMyfuncs;

我们在myfunc.c文件中使用它

void *glbfuncs=NULL
glbfuncs = dlopen("glbfuncs.so",RTLD_NOW);
initMyfuncs_t _initMyfuncs=NULL;
_initMyfuncs = dlsym(glbfuncs, "_initMyfuncs");

通常,我们在使用此函数指针或变量的文件或其他头文件中使用extern。 在这里,我们在头文件中声明了extern,并在同一源文件中使用了它。 在这里使用extern有什么用

并且此函数指针没有其他外部声明即可用于其他源文件中。 我对此感到困惑吗? 通常,我们在某处(somehere.h)有一个声明,如果在其他文件(here.h或here.c)中使用它,则使用extern关键字只是为了获取此变量。

我不太了解在typedef之后使用extern关键字的原因。

为什么在同一头文件中的fucntion指针声明之后使用extern?

需要extern关键字来区分全局数据对象(例如函数指针)的声明和该对象的定义。

在头文件中,您仅应具有声明。 定义属于源文件,不应在不同的源文件中重复。 如果将定义放在头文件中,则在链接时最终会得到相同符号的多个定义。 由于历史原因,如果普通链接程序没有初始化程序,它们会接受这些多个定义。 但是,这被认为是不良做法,应避免使用。

myfuncs.h

extern initMyfuncs_t _initMyfuncs; // declaration of function pointer

myfuncs.c

initMyfuncs_t _initMyfuncs = some_function;  // actual definition of the pointer with optional initializer.

混淆来自于函数指针的typedef,与函数原型不同。 函数原型甚至是没有extern关键字的声明。

extern int a;

是的declaraton a 这是(只是)一个编译器承诺 a将围绕在链接时。

它的实际定义需要在其他地方完成,通常在.c文件中通过

int a = 42; /* The initialiser is optional, if missing it will default to '= 0'. */

上面的概念对于任何类型都是相同的。

头文件可以包含在许多源文件中。 没有extern关键字,也将分配存储空间。 在头文件中没有extern关键字的情况下,将在每个包含头文件的源文件中分配此存储。 在链接时,链接器现在将抱怨多个符号(某些链接器可以正常解决此问题)。

为了避免这种情况,但不必在源文件中单独声明对象,我使用以下方法:

/* myInclude.h */
#ifndef EXTERN
# define EXTERN extern
#endif
EXTERN int myGlobalVar;

/* someFile.c */
#include "myInclude.h"

/* main.c */
#define EXTERN
#include "myInclude.h"

这将在main.c为对象分配存储,并在所有其他源文件(包括头文件)中将其声明为extern

我想我得到了答案

1,如果没有使用extern头,那么如果我们使用相同的变量(initMyfuncs_t _initMyfuncs = nullptr;)

  1. 或者我们可以只提及typedef函数指针并在源文件中初始化变量

myfuncs.h

typedef void(*initMyfuncs_t)(int*, int*, int*);

并在源代码myfuncs.c中初始化它

initMyfuncs_t _initMyfuncs = nullptr;     

如果我们需要在头文件中声明

myfuncs.h

typedef void(*initMyfuncs_t)(int, int, int);
extern  initMyfuncs_t _initMyfuncs;

并在源文件中初始化

initMyfuncs_t _initMyfuncs = nullptr;

最后,当在任何源文件中使用此头文件时,也可以使用此变量,因为我们在其中声明了extern

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM