我相信源文件中的静态函数不能直接从文件外调用。但是,如果我以某种方式设法将此函数的指针转换为另一个文件,那么我可以从该文件调用此函数。如果是的话,是否有任何情况下我们想采取这种路线,而不是简单地使该功能非静态?可以通过C中的函数指针调用静态函数吗?
回答
是的,你可以通过发出指向它们的静态函数。这是在C语言中实现Factory pattern的常用方法,您可以在其中隐藏使用它们的模块中的一大堆函数的实现,并且有一个FuncPtr_t GetFunction(enum whichFunctionIWant)
将它们传递给消费者。这就是多少个dynamic linking实现的工作。
是的,文件中的非静态函数可以将指向静态函数的指针返回到任何你喜欢的位置。
但是,如果我设法得到一个指向这个函数的指针到 另一个文件,我可以从那个文件中调用这个函数。
是的,这是完全可能的。该函数对链接器不可见,但它在可执行文件中。你总是可以跳转到它的地址。
虽然我不确定情况。也许你想让其他人只在之后调用你的函数他们调用了一些其他函数(当然是非静态的)。所以你有他们它获得它,然后他们可以打电话给它。
是的,你可以。如果您必须调用一个函数,该函数将函数的指针视为回调函数,则可以使用static,以便函数符号不会污染全局名称空间,并且不会导致链接器冲突。最常用的例子可能是qsort:
struct Data { ... };
static int compareData(const void* a, const void* b) { /* cast to Data and compare */ }
...
qsort(array, count, sizeof(Data), &compareData);
正如另一个提到的,你可以做到这一点。为什么你可能想要某种“驱动程序”的例子。您可以传回包含开放,关闭,读取和写入功能的结构,而无需公开实际的功能。
是的,你可以,你总是可以自己尝试,并找出:
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();
}
这在C中通常不是一个好方法。“它有效”和“它是安全的,可以在任何地方工作,并且不依赖于未定义的行为”通常是非常不同的事情。 –
它往往是用于定义一个小的静态函数作为另一个工作者函数。看一下标准qsort
的例子:它需要一个比较函数,而且通常最好是将该比较函数设置为静态的(例如,因为它在其他地方没有用处,并且因为qsort
希望它具有一些无害的签名)。
- 1. 通过函数指针静态调用虚函数
- 2. C++调用静态函数指针
- 3. 通过函数指针使用的函数可以内联吗?
- 4. C++通过函数指针调用函数中的矢量
- 5. C++通过函数指针指向另一个函数指针
- 6. C - 通过函数动态数组写指针,指针
- 7. 通过非静态成员函数指针在C++
- 8. 通用指针调用C函数
- 9. C++调用函数指针
- 10. 无法通过静态方法调用指向成员函数的指针
- 11. C - 不带函数指针的动态函数调用
- 12. 如何通过函数指针和参数在C++中调用函数
- 13. 如何通过此函数的指针调用winapi函数?
- 14. C++:通过基类中定义的函数指针派生函数调用
- 15. C++通过main函数中的类函数传递指针
- 16. 如何从静态成员函数调用指向成员函数的指针?
- 17. C++函数指针和回调函数
- 18. 通过函数指针重载函数
- 19. 静态模板函数可以通过编译器内联吗?
- 20. c函数指针反函数指针
- 21. 函数指向非静态成员函数的指针?
- 22. 现有的静态方法可以使用函数指针进行全局吗?
- 23. 如何通过成员函数指针调用成员函数?
- 24. 静态函数调用非静态函数在C++
- 25. 函数指针的静态映射
- 26. 如何通过函数指针调用具有不同签名的C++函数
- 27. C++模板函数跳过一个静态函数调用
- 28. C - 通过函数调用迷路的双指针
- 29. 函数指针指向非静态函数
- 30. 将指针转换为成员函数指向静态函数
我想知道如果你将这与'inline'关键字和/或专有的编译器指令混合使用,它总是内联一个函数,那么行为是什么。 – mpontillo
@mpontillo我相信,即使函数被标记为“inline”,但地址是在函数指针中取得的,编译器会在二进制文件中生成主体,同时也将其内联到同一模块中的其他函数中。 –