Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中安全地包含C代码+;对象包装器_C++ - Fatal编程技术网

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

我有一个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 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++库包装在C++对象包装器
  • 在单独的编译单元中“隐藏”C头
    myCtype.h
    , 使用包装器
  • 与C++代码无关
  • 确保所有地方的类型安全

在单个编译单元中隔离库代码并用自己的接口包装它实际上是一项非常常见的设计任务。显然,除了void类型指针之外,您的解决方案与您想要的非常接近

转发声明可以为您解决这个问题,但我假设
myCtype
typedef
?如果是这样的话,我将建议您稍微打破隔离,并查看库标题。Say
myCtype
的定义如下:

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
文件中,实际定义或声明是放在第一位并不重要。只要在首次使用之前声明了所有内容,并且在首次访问之前定义了成员,编译器就会很高兴。再次感谢!