C++ 在C+中安全地包含C代码+;对象包装器
我有一个C库,它定义了一个类型,比如说,C++ 在C+中安全地包含C代码+;对象包装器,c++,C++,我有一个C库,它定义了一个类型,比如说,myCtype,还有一些例程使用myCtype类型的变量。我想把C++对象定义为单个 MyCype < /Cuff>变量的包装器。假设包含myCtype定义的C头是myCtype.h。一个C++代码,其中包含了头文件>代码MyWraseP.HPP,代码实现在MyWraseP.CPP >看起来像 mywrapper.hpp: extern "C" { #include "myCtype.h" } class mywrapper { myCtype
myCtype
,还有一些例程使用myCtype
类型的变量。我想把C++对象定义为单个<代码> MyCype < /Cuff>变量的包装器。假设包含myCtype
定义的C头是myCtype.h
。一个C++代码,其中包含了头文件>代码MyWraseP.HPP<代码>,代码实现在mywrapper.hpp
:
extern "C" {
#include "myCtype.h"
}
class mywrapper
{
myCtype v;
public:
//...
// Constructor and some methods here
// ...
}
#include "mywrapper.hpp"
// ...
// Constructor and methods of mywrapper here
// ...
class mywrapper
{
void *v;
public:
mywrapper();
virtual ~mywrapper();
//...
// some methods here
// ...
}
#include "mywrapper.hpp"
#include <cstdlib>
extern "C" {
#include "myCtype.h"
}
mywrapper::mywrapper() : v(malloc(sizeof(myCtype)))
{
// Some initialization of v here
}
virtual mywrapper::~mywrapper()
{
free(v);
}
// ...
// Methods of mywrapper here
// ...
mywrapper.cpp
:
extern "C" {
#include "myCtype.h"
}
class mywrapper
{
myCtype v;
public:
//...
// Constructor and some methods here
// ...
}
#include "mywrapper.hpp"
// ...
// Constructor and methods of mywrapper here
// ...
class mywrapper
{
void *v;
public:
mywrapper();
virtual ~mywrapper();
//...
// some methods here
// ...
}
#include "mywrapper.hpp"
#include <cstdlib>
extern "C" {
#include "myCtype.h"
}
mywrapper::mywrapper() : v(malloc(sizeof(myCtype)))
{
// Some initialization of v here
}
virtual mywrapper::~mywrapper()
{
free(v);
}
// ...
// Methods of mywrapper here
// ...
这个方法的问题是C报头<代码> MyCyty.h < /C>可能包含几个“C样式”宏、定义和内联函数,这些函数可能与C++代码的其余部分冲突。code>mywrapper.hpp需要包含
myCtype.h
,因为定义了myCtype
。因此,每当我想使用<代码> MyWrasPer-<代码>是一个C++代码时,我就需要包含<代码> MyWrasPer-Hpp,这将汇集不必要的<代码> MyCype。
即使<代码> MyCype .h <代码>的定义和内联函数与当前C++代码不冲突,但最好将它们隐藏在C++代码中。
注意,我不需要myCtype
成员mywrapper::v
可见,因为我声明它是私有的。因此,出于所有的目的,使用<代码> MyWrasPer-<代码>的C++代码完全忽略了<代码> MyCyt[H]代码/< > /P>的内容。
这个问题的一个解决方案是使用void*
指针来保存myCtype
的实例,如下所示
mywrapper.hpp
:
extern "C" {
#include "myCtype.h"
}
class mywrapper
{
myCtype v;
public:
//...
// Constructor and some methods here
// ...
}
#include "mywrapper.hpp"
// ...
// Constructor and methods of mywrapper here
// ...
class mywrapper
{
void *v;
public:
mywrapper();
virtual ~mywrapper();
//...
// some methods here
// ...
}
#include "mywrapper.hpp"
#include <cstdlib>
extern "C" {
#include "myCtype.h"
}
mywrapper::mywrapper() : v(malloc(sizeof(myCtype)))
{
// Some initialization of v here
}
virtual mywrapper::~mywrapper()
{
free(v);
}
// ...
// Methods of mywrapper here
// ...
mywrapper.cpp
:
extern "C" {
#include "myCtype.h"
}
class mywrapper
{
myCtype v;
public:
//...
// Constructor and some methods here
// ...
}
#include "mywrapper.hpp"
// ...
// Constructor and methods of mywrapper here
// ...
class mywrapper
{
void *v;
public:
mywrapper();
virtual ~mywrapper();
//...
// some methods here
// ...
}
#include "mywrapper.hpp"
#include <cstdlib>
extern "C" {
#include "myCtype.h"
}
mywrapper::mywrapper() : v(malloc(sizeof(myCtype)))
{
// Some initialization of v here
}
virtual mywrapper::~mywrapper()
{
free(v);
}
// ...
// Methods of mywrapper here
// ...
#包括“mywrapper.hpp”
#包括
外部“C”{
#包括“myCtype.h”
}
mywrapper::mywrapper():v(malloc(sizeof(myCtype)))
{
//这里是v的一些初始化
}
虚拟mywrapper::~mywrapper()
{
免费(五);
}
// ...
//这里的mywrapper方法
// ...
<>现在,只有代码> MyWrasPer-.CPP< /C>的编译单元包含<代码> MyCype。h < /C> >,C++代码包括<代码> MyWrasPer-Hpp不带来<代码> MyCype。
但是,此解决方案附带使用void*
指针的类型unsafety
有更好的解决办法吗?它应当:
- 在单独的编译单元中“隐藏”C头
, 使用包装器myCtype.h
与C++代码无关
- 确保所有地方的类型安全
myCtype
是typedef
?如果是这样的话,我将建议您稍微打破隔离,并查看库标题。SaymyCtype
的定义如下:
typedef结构\u myCtype{
//成员们。。。
}myCtype
那么你的C++头可以是这样的:
类mywrapper
{
结构_myCtype*v;
//更多成员。。。
}
请注意,为了实现这一点,
mywrapper.hpp
不需要包含myCtype.h
头,因为它是一个转发声明。但是在您的mywrapper.cpp
中,如果在顶部包含myCtype.h
,则成员v
将被视为一个适当的myCtype
指针,而不需要强制转换。extern“C”
并不意味着您有C代码,它只更改了ABI。而且头不是库,你想知道一个头实际上是什么,它是理解你的问题的。C头应该是固定的,这样它就不会与C++(和其他C)代码冲突。你可能想也可能不想孤立它,所以这里没有“更好”的选择。我不确定我是否会受到批评。1)当然,代码>外部“C”<代码>只更改链接,但如关键字所示,它用于汇集C和C++代码。2) 问题中描述的问题当然可能在其他情况下出现,但我认为我已经把一个案例做得足够具体:事实上,我已经获得了一个令人满意的解决方案。谢谢!实际上,myCtype
是结构的typedef
。我想如果你把mywrapper::v定义为myCtype(即,不是指针,而是一个普通变量),你的解决方案也会起作用,对吧?恐怕不行。转发声明仅适用于指针(或引用)。如果将mywrapper::v
声明为非指针类型,那么编译器需要知道struct\u myCtype
的详细信息,例如,在分配mywrapper
的实例时,它有多大。由于所有指针的长度都相同,因此对于\u myCtype*
指针,这是不必要的。此机制是所有转发声明的基础。感谢您的澄清。还有一个问题:在mywrapper.cpp
中,的顺序是否包括“mywrapper.hpp”
和#包括“myCtype.h”
重要?不客气。那么你会接受我的答案作为正确的解决方案吗?不,别担心。在.cpp
文件中,实际定义或声明是放在第一位并不重要。只要在首次使用之前声明了所有内容,并且在首次访问之前定义了成员,编译器就会很高兴。再次感谢!