我怎么能在C中使用声明但未定义的函数呢?

时间:2017-03-22 02:58:50

标签: c function undefined declare

所以我想做的是我想在未来为自己创建一种框架,但我意识到我做不了什么。它是这样的:

void whenPressedQ();
void whenPressedW();
...
void checkPressQ(){
    whenPressedQ();
    printf("Q was pressed");
}
...
void whenPressedW(){
    doThings();
}

稍后我将定义这些函数并选择使用它们。

问题是如果我没有在下面定义它们,我不能为其他功能执行此操作。我收到“未定义函数”错误。有什么办法可以解决这个问题吗?我已经尝试使用函数指针并检查它是否为null但是它是一样的。

2 个答案:

答案 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

然后,您可以稍后直接链接目标文件,或者从中构建静态或动态库。