从C ++到C的转换

时间:2010-12-25 00:31:04

标签: c++ c

您好   我感兴趣的是将一些代码从C ++转换为C(主要是因为我需要使用带有/来自其他C程序和其他语言的库)。 C是一个更好的网关 我有兴趣复制一些C ++概念,比如inst。继承。

有没有人知道好的推荐或已经处理过一些类似的问题。对于inst如何处理继承,将新成员变量/方法添加到子类,...

感谢您的帮助

2 个答案:

答案 0 :(得分:7)

如果你需要从C调用lib,我会设计一个内部调用C ++函数的干净的C API。 C和C ++之间的链接是不同的,因此,您必须指定:

#ifdef __cplusplus
extern "C" { 
#endif

void my_c_function (void );

#ifdef __cplusplus
}
#endif

关于设计,你必须隐藏类,模板等。我建议你阅读一些C库,比如libpng或OpenGL 1.0,以了解纯C接口。

在C中,您必须自己构造和删除“对象”。如果在每次调用中为“对象”传递“this”指针,则可以使用某种面向对象的编程。

但不幸的是,你会有类似“无效指针”的东西。如果您不想暴露内部存储器,可以使用句柄(如win32)。

答案 1 :(得分:4)

以下是一个快速示例,说明如何在C调用API中包装C ++类或API,只需将C调用转发给C ++对象。

假设您有一个带有以下接口的C ++库:

class stopwatch
{
public:
    void start();
    void stop();
    void reset();

    unsigned int get_elapsed();

private:
    // whatever...
};

您的C API可能具有以下标题所描述的界面:

#ifndef STOPWATCH_API_H
#define STOPWATCH_API_H

#if __cplusplus
extern "C" {
#endif


struct stopwatch_handle;

stopwatch_handle* stopwatch_create(void);
void stopwatch_delete( struct stopwatch_handle*);

void stopwatch_start(struct stopwatch_handle*);
void stopwatch_stop(struct stopwatch_handle*);
void stopwatch_reset(struct stopwatch_handle*);
void stopwatch_get_elapsed(struct stopwatch_handle*);


#if __cplusplus
}
#endif
#endif

请注意,上述标题旨在包含在C或C ++模块中,并且在C ++模块中编译时,相应的部分标记为extern "C"

现在,该C API的实现是在.cpp模块中完成的,因此它可以访问C ++库,但它提供了C-callable接口。

#include <new>  // for nothrow new
#include "stopwatch.h"  // the C++ library API
#include "stopwatch_api.h"  // the C callable interface that's being
                            //   implemented here

struct stopwatch_handle {
    stopwatch impl;   // the C code never needs to know about this
                      // internal part of the struct, since all that
                      // the C client code will deal with is an
                      // opaque pointer
};


extern "C"
stopwatch_handle* stopwatch_create(void)
{
    // use nothrow new since it doesn't make sense to 
    // have an exception bubble up to C code
    return new(std::nothrow) stopwatch_handle;
}


extern "C"
void stopwatch_delete( struct stopwatch_handle* p)
{
    delete p;
}


extern "C"
void stopwatch_start(struct stopwatch_handle* p)
{
    p->impl.start();
}


extern "C"
void stopwatch_stop(struct stopwatch_handle* p);
{
    p->impl.stop();
}


extern "C"
void stopwatch_reset(struct stopwatch_handle* p)
{
    p->impl.reset();
}


extern "C"
unsigned int stopwatch_get_elapsed(struct stopwatch_handle* p)
{
    return p->impl.get_elapsed();
}

请注意,在stopwatch_create()函数中,我们调用运算符new的变体,它不会在失败时抛出异常,因为这通常没有意义(除非您预期异常应该终止程序或在堆栈中将有一个适当的处理程序)。如果他们需要处理可能的异常并将它们“转换”为适合C的错误处理机制,那么这种情况可能会使您的C API函数变得更复杂。