2011-11-05 64 views
25

我相信源文件中的静态函数不能直接从文件外调用。但是,如果我以某种方式设法将此函数的指针转换为另一个文件,那么我可以从该文件调用此函数。如果是的话,是否有任何情况下我们想采取这种路线,而不是简单地使该功能非静态?可以通过C中的函数指针调用静态函数吗?

+1

我想知道如果你将这与'inline'关键字和/或专有的编译器指令混合使用,它总是内联一个函数,那么行为是什么。 – mpontillo

+0

@mpontillo我相信,即使函数被标记为“inline”,但地址是在函数指针中取得的,编译器会在二进制文件中生成主体,同时也将其内联到同一模块中的其他函数中。 –

回答

28

是的,你可以通过发出指向它们的静态函数。这是在C语言中实现Factory pattern的常用方法,您可以在其中隐藏使用它们的模块中的一大堆函数的实现,并且有一个FuncPtr_t GetFunction(enum whichFunctionIWant)将它们传递给消费者。这就是多少个dynamic linking实现的工作。

3

是的,文件中的非静态函数可以将指向静态函数的指针返回到任何你喜欢的位置。

9

但是,如果我设法得到一个指向这个函数的指针到 另一个文件,我可以从那个文件中调用这个函数。

是的,这是完全可能的。该函数对链接器不可见,但它在可执行文件中。你总是可以跳转到它的地址。

虽然我不确定情况。也许你想让其他人只在之后调用你的函数他们调用了一些其他函数(当然是非静态的)。所以你有他们它获得它,然后他们可以打电话给它。

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); 
4

正如另一个提到的,你可以做到这一点。为什么你可能想要某种“驱动程序”的例子。您可以传回包含开放,关闭,读取和写入功能的结构,而无需公开实际的功能。

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(); 
} 
+8

这在C中通常不是一个好方法。“它有效”和“它是安全的,可以在任何地方工作,并且不依赖于未定义的行为”通常是非常不同的事情。 –

2

它往往是用于定义一个小的静态函数作为另一个工作者函数。看一下标准qsort的例子:它需要一个比较函数,而且通常最好是将该比较函数设置为静态的(例如,因为它在其他地方没有用处,并且因为qsort希望它具有一些无害的签名)。

相关问题