我认为源文件中的静态函数不能直接从文件外部调用。但是,如果我以某种方式设法将指向此函数的指针转换为另一个文件,那么我可以从该文件中调用此函数。如果是的话,是否有任何情况我们想采用这种方式而不是简单地使函数非静态?
答案 0 :(得分:31)
是的,您可以通过分发指向它们的指针来导出静态函数。这是在C中实现Factory pattern的常用方法,您可以从使用它们的模块中隐藏一大堆函数的实现,并使用FuncPtr_t GetFunction( enum whichFunctionIWant)
将它们交给消费者。这就是有多少dynamic linking个实现工作。
答案 1 :(得分:9)
但是,如果我以某种方式设法获得指向此函数的指针 另一个文件,然后我可以从该文件中调用此函数。
是的,这是完全可能的。该功能对链接器不可见,但它位于可执行文件中。你总是可以跳到它的地址。
我不确定情况。也许你希望别人只在之后调用你的函数他们调用了其他函数(当然是非静态函数)。所以你让他们获取它,然后他们可以调用它。
答案 2 :(得分:4)
如前所述,你可以做到。您可能想要的原因的一个例子是某种“驱动程序”。您可以传回包含open,close,read和write函数的结构,而无需公开实际的函数。
答案 3 :(得分:3)
是的,文件中的非静态函数可以将指向静态函数的指针返回到您喜欢的任何位置。
答案 4 :(得分:3)
是的,你可以。如果必须调用一个需要指向函数指针作为回调的函数,则可以使用static,这样函数符号就不会污染全局命名空间,也不会导致链接器冲突。最常用的例子可能是qsort:
struct Data { ... };
static int compareData(const void* a, const void* b) { /* cast to Data and compare */ }
...
qsort(array, count, sizeof(Data), &compareData);
答案 5 :(得分:2)
将一个小的静态函数定义为另一个函数的worker函数通常很有用。查看标准qsort
的示例:它需要一个比较函数,并且通常最好将比较函数设置为静态(例如,因为它在其他地方没用,并且因为qsort
想要它有一些不合时宜的签名。)
答案 6 :(得分:0)
是的,你可以,你总是可以自己尝试并找出:
file1.c中
#include <stdio.h>
void call_hello(void (*fptr)(void));
static void hello(void) {
puts("hello");
}
int main(void)
{
void (*fptr)(void) = hello;
call_hello(fptr);
return 0;
}
file2.c中
void call_hello(void (*fptr)(void))
{
fptr();
}