所以我想做的是我想在未来为自己创建一种框架,但我意识到我做不了什么。它是这样的:
void whenPressedQ();
void whenPressedW();
...
void checkPressQ(){
whenPressedQ();
printf("Q was pressed");
}
...
void whenPressedW(){
doThings();
}
稍后我将定义这些函数并选择使用它们。
问题是如果我没有在下面定义它们,我不能为其他功能执行此操作。我收到“未定义函数”错误。有什么办法可以解决这个问题吗?我已经尝试使用函数指针并检查它是否为null但是它是一样的。
答案 0 :(得分:1)
您可以将指针传递给回调函数,或者将它们包装在结构中,然后让库传回指向稍后匹配签名的函数的指针,即使是将来要编写的函数。这就是第一批C ++编译器如何实现对象的虚拟方法。
如果您只是想在编译未实现的函数时编译代码,可以创建虚拟存根函数来关闭链接器。
以下是我的意思的一些例子。你的问题有些含糊不清。如果您要问的是如何声明您打算稍后实现的函数,并且仍然能够编译该程序,那么答案就是提供存根。这是你界面的MCVE:
#include <stdio.h>
#include <stdlib.h>
/* In older versions of C, a declaration like void doThings() would turn
* type-checking of function arguments off, like for printf().
*/
void whenPressedQ(void);
void whenPressedW(void);
void doThings(void); // Added this declaration.
void checkPressQ()
{
whenPressedQ();
printf("Q was pressed.\n"); // Don't forget the newline!
}
void whenPressedW()
{
doThings();
}
// Stub implementations:
void whenPressedQ(void)
// FIXME: Print an error message and abort the program.
{
fflush(stdout); // Don't mix the streams!
fprintf( stderr, "Unimplemented function whenPressedQ() called.\n" );
exit(EXIT_FAILURE);
}
void doThings(void)
// Is nothing a thing?
{}
// Test driver:
int main(void)
{
whenPressedW();
whenPressedQ(); // fails;
// Not reached.
return EXIT_SUCCESS;
}
如果你想让程序动态选择要调用哪个函数,那就更复杂了,但你可以用回调来做。这是一个简单的例子。
#include <stdio.h>
#include <stdlib.h>
// This would ordinarily go in a .h file:
typedef const char*(*callback_t)(void); // The type of a callback function.
extern callback_t get_the_answer(void);
// This would ordinarily go in a .c file:
int main(void)
{
callback_t ask_the_question = get_the_answer();
printf( "The answer to life, the Universe and Everything is %s.\n",
ask_the_question()
);
return EXIT_SUCCESS;
}
// This would ordinarily go in another .c file:
static const char* the_answer_is(void)
{
return "42";
}
callback_t get_the_answer(void)
{
return &the_answer_is;
}
答案 1 :(得分:0)
您收到链接器错误的错误。如果您不是在尝试构建可执行文件,那么您只需编译即可进行链接。在Linux / OS X上,您可以将-c
标志传递给clang或gcc。在Windows上,您可以在编译时将/c
标记传递给cl.exe
。
然后,您可以稍后直接链接目标文件,或者从中构建静态或动态库。