我最近了解到:
int a;
at file scope是一个变量声明,默认情况下具有外部链接。
cat >lib.c <<'EOF'
#include "lib.h"
#include <stdio.h>
#include <stdint.h>
// This is declaration
// It will be initialized to NULL in case no definition is found
void (* const lib_callback_pnt)(int);
void lib_callback_default(int a)
{
printf("%s %d\n", __func__, a);
}
void lib_call(int a)
{
printf("%s calling %p\n", __func__,
// this is not really portable
(void*)(uintptr_t)(intmax_t)lib_callback_pnt
);
// call callback
void (* const lib_callback_to_call)(int) =
lib_callback_pnt == NULL
? lib_callback_default
: lib_callback_pnt;
lib_callback_to_call(a);
}
EOF
cat >lib.h <<'EOF'
#ifndef LIB_H_
#define LIB_H_
extern void (* const lib_callback_pnt)(int);
void lib_callback_default(int a);
void lib_call(int a);
#endif
EOF
cat >main1.c <<EOF
#include "lib.h"
int main() {
lib_call(42);
}
EOF
cat >main2.c <<'EOF'
#include "lib.h"
#include <stdio.h>
static void my_lib_callback(int a)
{
printf("Hah! Overwritten lib callback!\n");
}
// this is definition
void (* const lib_callback_pnt)(int) = my_lib_callback;
int main() {
lib_call(42);
}
EOF
cat >Makefile <<'EOF'
CC=gcc
CFLAGS=-Wall -Wextra -pedantic -std=c11
all:
$(CC) $(CFLAGS) lib.c main1.c -o main1
$(CC) $(CFLAGS) lib.c main2.c -o main2
EOF
lib.c
库我声明了一个函数指针
void (* const lib_callback_pnt)(int)
文库
然后我有两个程序或用户应用程序,即
main1.c
main2.c
.
这个
只需调用调用回调的库函数-回调没有初始化,因此它默认初始化为NULL-我可以在库中比较并适当地调用默认回调/选择操作。
这个
但是声明函数指针
lib_callback_pnt
初始化-这是一个定义。所有源文件中都有一个此变量的定义,因此链接器不会抱怨多个符号定义。当我们调用库时,指针被初始化,因此用户应用程序
main2
我们可以编译:
$ make
gcc -Wall -Wextra -pedantic -std=c11 lib.c main1.c -o main1
gcc -Wall -Wextra -pedantic -std=c11 lib.c main2.c -o main2
打电话给:
$ ./main1
lib_call calling (nil)
lib_callback_default 42
$ ./main2
lib_call calling 0x5627c07871cf
Hah! overwritten lib callback!
问题: