我有一个关于(重新)定义函数的问题。我的目标是有一个脚本,我可以选择定义一个函数。 像这样:
void func(){}
int main(){
if (func)func();
}
没有这个功能,只需:
int main(){
if (func)func();
}
有人有想法吗?
答案 0 :(得分:16)
您可以使用其弱函数属性扩展名在GCC中执行此操作:
void func() __attribute__((weak)); // weak declaration must always be present
int main() {
if (func) func();
// ...
}
// optional definition:
void func() { ... }
即使在另一个.c文件或库中定义了func()
,这仍然有效。
答案 1 :(得分:5)
我认为这样的事情。没有多少使用函数指针,所以我的语法可能略有错误。
void func()
{
#define FUNC_PRESENT
// code
}
void (*funcptr)();
#ifdef FUNC_PRESENT
funcptr = func;
#else
funcptr = NULL;
#endif
int main()
{
if (funcptr)
funcptr();
}
答案 2 :(得分:4)
使用函数指针,根据运行时条件动态设置它们,并检查空指针或将它们包装在为您检查的方法中。
C中我只能考虑选项。
在C ++中,您可以组合模板和DLL以在运行时动态定义。
答案 3 :(得分:3)
您可以“选择是否定义函数”的唯一方法是使用C预处理程序指令。例如:
#ifdef some_name
void func() {
do_whatever();
}
#else
//the else part is optional
#endif
要设置这些“变量”,请使用#define some_name
麻烦的是,所有这些都需要在编译时完成(在此之前,实际上),所以不能像你的例子那样使用if
语句来完成。如果你想要一个if语句来控制你的程序流程,只需使用它,不要试图重命名函数或使用函数指针等。
答案 4 :(得分:1)
我猜你正在尝试这样做:
a.o
和b.o
b.o
包含void foo()
a.o
也链接到最终的可执行文件,则void foo()
仅调用b.o
。这对于“插件”系统非常有用。
您可以使用函数指针进行模拟。我不知道足够的C用适当的C代码写这个,但伪代码看起来像这样:
extern collectionOfFuncPtrs_t list;
int addFuncPtr();
#include "a.h"
collectionOfFuncPtrs_t list;
int addFuncPtr(FuncPtr p) {
- add func ptr to list
- return 0
}
int main() {
- loop through list of function pointers
- call functions through them
}
#include "a.h"
void bar() { /* ... */ }
static int dummy = addFuncPtr(&bar);
#include "a.h"
void ayb() { /* ... */ }
static int dummy = addFuncPtr(&ayb);
现在,您可以根据需要链接到b.o
和/或c.o
,int main()
只会调用bar()
和/或ayb()
存在。
尝试使用此主题的变体,如果它看起来可能对您有用。特别是,如果你只有一个特定数量的条件定义函数,你可以使用一堆单独的函数指针而不是一些列表:
extern fptr_t bar_ptr, ayb_ptr;
#include "a.h"
int main() {
if (bar_ptr)
bar_ptr();
if (ayb_ptr)
ayb_ptr();
}
#include "a.h"
void bar() { /* ... */ }
fptr_t bar_ptr = &bar;
#include "a.h"
fptr_t bar_ptr = 0;
#include "a.h"
void ayb() { /* ... */ }
fptr_t ayb_ptr = &ayb;
#include "a.h"
fptr_t ayb_ptr = 0;
现在链接b.o
或b_dummy.o
;并链接c.o
或c_dummy.o
。
我希望你能得到一般的想法,无论如何......!
在C ++中,这是 lot 更容易,您可以使用std::map
和构造函数轻松编写模块注册系统。
答案 5 :(得分:0)
在C?只能使用其他答案中所述的预处理器。
C不是一种动态语言,比如Python。
答案 6 :(得分:0)
我认为您在C中提出的问题的正确方法是使用function pointers。您可以获取函数的地址,将其分配给变量,将其测试为nil等。但是,普通的旧C不是一种非常动态的语言;你可能最好使用不同的语言。
答案 7 :(得分:0)
如果您不介意编译器特定的扩展程序,可以使用AdminUserGlobalSignOut
:
__if_exists
默认情况下在msvc中有效,如果使用#include <iostream>
using namespace std;
// uncomment the following, and it'll still work
void maybeFunc(){ cout << "running maybe" << endl; }
int main(){
cout << "hi!" << endl;
__if_exists(maybeFunc)
cout << "maybe exists!" << endl;
maybeFunc();
}
}
标志,则在clang中有效。