如何使用宏或其他机制强制执行 API 定义?
How to enforce an API definition with macros or some other mechanism?
我有一个 C 头文件作为我正在开发的 API 的一部分,它公开了许多函数。例如:
api.h
void foo();
int bar(char * foobar);
现在,我公开的大多数功能实际上都在 API 中定义,但是,我留给使用开发人员自己实现一些功能。为了让开发人员更容易并强制遵守我的 API 我添加了以下宏:
api.h(修改)
#define DEFINE_FOO() \
void foo()
void foo();
#define DEFINE_BAR() \
int bar(char * foobar)
int bar(char * foobar);
使用如下:
implement.c
#include "api.h"
DEFINE_FOO() {
// Codez
}
DEFINE_BAR() {
// More codez
}
关于这种方法的一个困扰我的事情是开发人员将使用 DEFINE_* 宏,但不一定凭直觉认为函数 "bar" 接受参数。有没有办法改进这种方法,或者有更好的方法来在 C 中强制执行自定义 API 定义?谢谢!
我不会真的推荐你的方法,但你可以在技术上让它发挥作用。
您可以像这样将参数传递给宏:
#define DEFINE_BAR(arg) \
int bar(char* arg)
现在程序员可以调用
DEFINE_BAR(arg_name) {
return strlen(arg_name);
}
这将被cpp变成如下:
int bar(char* arg_name) {
return strlen(arg_name);
}
真的没有必要使用宏,我建议不要使用它(而且我在 [过去 35 +] 年)。
如果您正在定义 API,这意味着您将 api.h
中的 [ANSI] 原型用于 所有 函数。这并不意味着 你 将实现它们——它只意味着你定义 architecture/API。 api.h
中没有原型的任何函数都不属于 API [显然]。
如果您这样做,编译器将标记任何不匹配项。只需要求开发人员在顶部包含 api.h
。
这是一个 api.h
:
void foo(void);
int bar(char *foobar);
符合标准的 .c
将编译干净:
#include "api.h"
#include <stdio.h>
void
foo(void)
{
}
int
bar(char *str)
{
return 0;
}
不一致的.c
将不能正确编译:
#include "api.h"
#include <stdio.h>
void
foo(int x)
{
printf("foo: %d\n",x);
}
int
bar(char *str)
{
return 0;
}
你会得到编译错误:
bad.c:5:1: error: conflicting types for ‘foo’
foo(int x)
^
In file included from bad.c:1:0:
api.h:2:6: note: previous declaration of ‘foo’ was here
void foo(void);
^
因此,如果开发人员犯了错误,普通的代码定义会处理它。
我有一个 C 头文件作为我正在开发的 API 的一部分,它公开了许多函数。例如:
api.h
void foo();
int bar(char * foobar);
现在,我公开的大多数功能实际上都在 API 中定义,但是,我留给使用开发人员自己实现一些功能。为了让开发人员更容易并强制遵守我的 API 我添加了以下宏:
api.h(修改)
#define DEFINE_FOO() \
void foo()
void foo();
#define DEFINE_BAR() \
int bar(char * foobar)
int bar(char * foobar);
使用如下:
implement.c
#include "api.h"
DEFINE_FOO() {
// Codez
}
DEFINE_BAR() {
// More codez
}
关于这种方法的一个困扰我的事情是开发人员将使用 DEFINE_* 宏,但不一定凭直觉认为函数 "bar" 接受参数。有没有办法改进这种方法,或者有更好的方法来在 C 中强制执行自定义 API 定义?谢谢!
我不会真的推荐你的方法,但你可以在技术上让它发挥作用。
您可以像这样将参数传递给宏:
#define DEFINE_BAR(arg) \
int bar(char* arg)
现在程序员可以调用
DEFINE_BAR(arg_name) {
return strlen(arg_name);
}
这将被cpp变成如下:
int bar(char* arg_name) {
return strlen(arg_name);
}
真的没有必要使用宏,我建议不要使用它(而且我在 [过去 35 +] 年)。
如果您正在定义 API,这意味着您将 api.h
中的 [ANSI] 原型用于 所有 函数。这并不意味着 你 将实现它们——它只意味着你定义 architecture/API。 api.h
中没有原型的任何函数都不属于 API [显然]。
如果您这样做,编译器将标记任何不匹配项。只需要求开发人员在顶部包含 api.h
。
这是一个 api.h
:
void foo(void);
int bar(char *foobar);
符合标准的 .c
将编译干净:
#include "api.h"
#include <stdio.h>
void
foo(void)
{
}
int
bar(char *str)
{
return 0;
}
不一致的.c
将不能正确编译:
#include "api.h"
#include <stdio.h>
void
foo(int x)
{
printf("foo: %d\n",x);
}
int
bar(char *str)
{
return 0;
}
你会得到编译错误:
bad.c:5:1: error: conflicting types for ‘foo’
foo(int x)
^
In file included from bad.c:1:0:
api.h:2:6: note: previous declaration of ‘foo’ was here
void foo(void);
^
因此,如果开发人员犯了错误,普通的代码定义会处理它。