如何在C程序中最好地使用单个C++类

4

我需要将一个C++类的代码导入/翻译,以便我可以在C程序中使用它。

C程序很大,并且有许多对开放和封闭C库的依赖。

C++类.cpp文件有650行

我没有混合使用C和C++的经验,即使我已经查看了一份指南,我仍然不确定该怎么做。

我只需要在几个地方使用C++代码(相当隔离的用法)

我正在使用gcc(gcc/g++)

这是一个Linux环境

那么我需要做什么才能导入它?是否比翻译更省时间?

谢谢,

迈克

7个回答

11
嗯,650行不算太长-我会重写它的。你可能需要花费至少同样多的时间来尝试修复它,并且可能会发现维护结果很困难。

7

6

您需要在C++中创建extern "C"函数,以便可以从C中调用。

您可以通过将this指针显式化(并且类型为void *)来实现OO,实现将指针转换并转发到实际成员函数。


5

在您的C++代码中,必须使用extern "C"结构来指示编译器/链接器生成兼容的链接,以便C代码可以调用您的C++代码。

extern "C"
{
   void my_function_that_can_be_called_from_c()
   {
      // ...
   }
}

C代码对于对象一无所知,因此您无法轻松地在C中使用C++对象。一种常用的技术是在“externed”函数内部操作C++对象。


5

假设你有以下C++类:

#if __cplusplus // only C++ programs see this part of foo.h

class foo {
public:
    // a couple constructors
    foo();

    foo( int);

    // and a couple methods
    bool dosomething();
    bool doSomethingElse( std::string const&);

private:
    // a bunch of private stuff which is immaterial to the C interface
}

#endif

你可以编写一组C-callable函数来封装C++接口。
// both C and C++ programs can see this part of foo.h

#if __cplusplus // but C++ programs need to know that no name mangling should occur
extern "C" {
#endif

struct CFoo_struct;
typedef struct CFoo_struct foo_t;   // used as a handle to a foo class pointer

// constructors

foo_t* CreateFoo( void);
foo_t* CreateFoo_int( int);

int CFooDoSomething( foo_t*);
int CFooDoSomethingElse( foo_t*, char const*);

#if __cplusplus
}               // end the extern "C" block
#endif

那么,在foo.cpp中的实现可能会像这样:

// in foo.cpp
extern "C" {

    struct CFoo_struct {
    };


    // constructors

    foo_t* CreateFoo( void) 
    {
        foo* pFoo = new Foo;

        // a bit of ugliness - the need for this cast could be 
        //  avoided with some overhead by having the foo_t
        //  struct contain a foo* pointer, and putting a foo_t
        //  structure inside the foo class initialized with 
        //  the this pointer.

        return reinterpret_cast<foo_t*>( pFoo);
    }

    // something similar for CreateFoo_int()...



    // method wrappers

    int CFooDoSomethingElse( foo_t* pHandle, char const* s)
    {
        foo* pFoo = reinterpret_cast<foo*>( pHandle);

        std::string str( s);

        return pFoo->doSomethingElse( str);
    }

    // something similar for CFooDoSomething()

} // end extern "C" block

1
如果你想将C++类转换为Linux共享库,以便让你的C程序可以访问,这个答案给出了一个小例子来展示如何实现。

1

有很多事情可以做。

你可以用C重写它。但是如果没有看到代码,我不知道这会有多大的麻烦。许多C++代码只是带有一些附加功能的C,而有些则大量使用模板和重载函数等。

如果你不这样做,你需要让它与C良好地通信。这意味着为C提供一个接口,并用extern "C"{ ... }将其包围起来,以便C++编译器知道如何使接口与C兼容。同样,如果不了解C++代码的某些内容,我无法告诉你这需要多少工作量。你需要为以下两种解决方案之一编写包装器。

你可以将其作为C++项目,用extern"C" { ... }包围每个C文件,然后链接它。如果有任何C++文件,则整个编译必须是C++。

你可以制作一个单独的库来链接。

你不能在C主函数中或使用C编译器将C和C++编译在一起。C++更加苛刻,需要主函数提供更多支持。

你可以尝试将你正在使用的C文件重新编译为C++,并将库的.h文件包装在extern "C" { ... }中。良好编写的C90与合法的C++相差不远(虽然C99标准有所偏移),编译器会标记任何转换问题。

哪种方法对你来说最好取决于以下问题: 将C++代码转换为多么容易? 编写C包装器以获取所需的C++功能有多容易? 你愿意对C代码进行多少更改? 你对制作Linux库有多熟悉?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接