另请参阅“如何将 C++ 类的对象传递给 C 函数或从 C 函数传递?” (C++ FAQ),但是我不确定如何将其应用到我的案例中。
我正在尝试从我的 C++ 源文件中公开 C 兼容类型(结构)。
我通过将结构“转换”为不同的方式使它们在理论上兼容。如何使这些“强制转换”类型可以通过 C 标头访问
c_header.h
?
cpp_header.hpp
#ifdef __cplusplus
template <typename T>
struct item {
uint32_t foo;
T data;
};
int bar(struct item<T> *item);
extern "C" {
typedef struct item<uint8_t> u8_item_t;
typedef struct item<uint16_t> u16_item_t;
}
#endif // __cplusplus
c_header.h
#include "cpp_header.hpp"
int bar_u8(u8_item_t *item);
int bar_u16(u16_item_t *item);
cpp_source.cpp
#include "cpp_header.hpp"
#include "c_header.h"
template <typename T>
int bar(struct item<T> *item) {
// ...
return 0;
}
extern "C" {
int bar_u8(u8_item_t *item) { return bar<uint8_t>(item); }
int bar_u16(u16_item_t *item) { return bar<uint16_t>(item); }
}
编译时,我看到的第一个错误是
c_header.h : error: unknown type name 'u8_item_t'
| int bar_u8(u8_item_t *item);
^~~~~~~~~
c_header.h : error: unknown type name 'u16_item_t'
| int bar_u16(u16_item_t *item);
^~~~~~~~~
问题在于 C 类型的 typedef 位于 C++ 保护范围内。不幸的是,如果你把它们移到外面,你在编译 C 的任何时候都会得到一个错误,因为 C 没有模板类型。
也许你最好的选择就是定义 C 不完整类型。您还需要为您使用的模板类型的每个变体提供一个单独的 C 函数,因为 C 无法区分它们 - 它们都是指针,而且也没有参数重载。
#ifdef __cplusplus
template <typename T>
struct item {
uint32_t foo;
T data;
};
int bar(struct item<T> *item);
extern "C" {
#endif
typedef struct u8_item_t u8_item_t;
typedef struct u16_item_t u16_item_t;
int bar_u8(u8_item_t *item);
int bar_u16(u16_item_t *item);
#ifdef __cplusplus
}
#endif // __cplusplus
bar_u8
和 bar_u16
是 shim 函数,它们的唯一目的是进行转换并调用模板函数。