我可以为任何可以放入 Extern C 的 C++ 向量制作一个 C 包装器吗
Posted
技术标签:
【中文标题】我可以为任何可以放入 Extern C 的 C++ 向量制作一个 C 包装器吗【英文标题】:Can I make one C wrapper for any C++ vector that could go in a Extern C 【发布时间】:2014-03-28 04:35:06 【问题描述】:我需要一个用于任何 C++ 向量的 C 包装器,它可以传递给需要某种特定类型向量的函数。就像我下面的 OpenCV 的 BRISK 的 C 包装器一样”
void cv_BRISK_generateKernel(BRISK* self, vector_float* radiusList,
vector_int* numberList, float dMax, float dMin, vector_int* indexChange)
self->generateKernel(*radiusList, *numberList, dMax, dMin, *indexChange);
vector_int*
和vector_float*
是typedef
,如下所示
typedef vector<int> vector_int;
typedef vector<float> vector_float;
这些是我目前拥有的矢量包装器,它们可以工作,但我想知道是否有一种方法可以为所有矢量类型制作一个包装器。它必须进入 Extern C..所以它不能是模板。但我不想使用下面的包装器,我只想制作一个包装器,它可以传递给一个期望 vector_float*
(typedef
for vector<float>
) 或 vector_KeyPoint*
(typedef
for vector<KeyPoint>
) 的函数或vector_int*
(typedef
for vector<int>
) 等。我知道模板类,但我不能在这里使用它们,因为它必须进入extern C
vector_float* std_create_vectorf()
return new vector<float>;
vector_int* std_create_vector()
return new vector<int>;
vector_char* std_create_vectorc()
return new vector<char>;
这是我理想化的包装如果有人可以帮助我弄清楚如何实现这一点,我将不胜感激
vector_any_vec* std_create_vectorany()
return new vector<anyvector>;
【问题讨论】:
你要找的基本上是一个没有使用模板类的模板类。我真的不认为这是可能的。至少你最终会返回一个void*
,这被认为是一个非常糟糕的主意。
@computerfreaker 感谢您回复我...你真的擅长 c++/c,我已经搜索了几次这个答案,但没有答案...如果我知道你是知识渊博,可能有助于给我指明方向……比如接受并继续前进等
我不是最擅长 C++,不,尤其是在模板类等更高级的东西方面。但是按照我看待您的问题的方式,您需要一个能够返回几乎任何数据类型的向量的函数。这意味着两件事之一:模板类(仍然需要一定程度的专业化)或void*
返回。模板类使用起来更干净、更安全,但您的extern "C"
req 使这成为不可能。从技术上讲,您可以将 void*
返回到适当类型的向量,但我不确定您如何告诉您的函数使用什么类型来制作 vector
。
【参考方案1】:
如何使用运行时多态性将其封装在一个接口中?你牺牲了一点类型安全,但它应该能满足你的需要。
enum stored_type
st_int,
st_float,
st_char
;
struct IGeneralVector
virtual stored_type get_type() = 0;
virtual void* get_data() = 0;
virtual ~IGeneralVector();
;
class VectorFloatHolder : public IGeneralVector
std::vector<float>* data;
public:
VectorFloatHolder(std::vector<float>* in) : data(in)
virtual stored_type get_type() override
return st_float;
virtual void* get_data() override
return reinterpret_cast<void *>(data);
virtual ~VectorFloatHolder()
delete data;
;
IGeneralVector* std_create_vectorf()
return new VectorFloatHolder(new std::vector<float>);
更新
阅读您的评论后,我对您想要实现的目标有了更好的了解。但是我不确定是否可以完全按照您的意愿去做,因为我不确定您有任何其他实现限制。这次是另一种使用类型擦除的方法。
class ObjectHolder
struct base_type
virtual ~base_type()
;
template<typename T>
struct object_type : base_type
object_type(const T& t) : object(t)
T object;
;
std::unique_ptr<base_type> data;
public:
template<typename T>
VectorHolder(T t) : data(new object_type<T>(t))
template<typename T>
T GetData()
object_type<T>* val = static_cast<object_type<T>*>(data.get());
return val->object;
;
template<typename T>
ObjectHolder* std_create_vector()
return new VectorHolder(new std::vector<T>);
int main()
ObjectHolder* vh = std_create_vector < std::vector<float>>();
// then later on you can get back the original type via:
std::vector<float>* fp = vh->GetData<std::vector<float>*>();
【讨论】:
...感谢您的回答。我很感激。但是我在函数调用中注意到它是IGeneralVector* std_create_vectorf()
...对于所有向量类型来说,这似乎仍然不是 1 个函数。它看起来就像一个浮点数。我在这里错过了什么吗?我只是希望有一个功能...一个我也许可以给int type
类型的 agrument 或键入它作为它正在使用...虽然我更喜欢前者...不过谢谢,如果我是不清楚,但您知道解决方案吗?
你知道吗,我非常感谢你到目前为止所花的时间。不过,我在帖子中确实提到了一件小事,它必须放在 Extern C 中……所以它不能是模板。 .你太好了,我不想把你赶出去,但你有解决这个问题的办法吗?这真的会回答很多?对我来说:)?以上是关于我可以为任何可以放入 Extern C 的 C++ 向量制作一个 C 包装器吗的主要内容,如果未能解决你的问题,请参考以下文章