在C程序中使用单个C++类的最佳方法

4 c c++

我必须从一个C++类导入/翻译代码,以便我可以在C程序中使用它.

C程序很大,对C库的开放和封闭都有很多依赖.

C++类.cpp文件是650行

我没有混合使用C和C++的经验,所以尽管我已经看过一个如何做的指南,但我不相信会走哪条路.

我只需要在几个地方使用C++代码(相当孤立的用途

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

这是一个Linux环境

那么我需要做什么才能导入呢?它会比翻译时间短吗?

谢谢,

麦克风

小智 11

嗯,650行不太长 - 我会重写它.您可能会花费至少尽可能多的时间来包装它,并且您可能会发现难以保持结果.


Ric*_*ard 6

你需要在C++中创建'extern"C"'的函数,所以它们可以从C调用.

您可以通过使this指针显式(并且类型为void*)来获得OO,实现转换指针并转发到真实成员函数.


Bri*_*eal 5

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

extern "C"
{
   void my_function_that_can_be_called_from_c()
   {
      // ...
   }
}
Run Code Online (Sandbox Code Playgroud)

C代码对对象一无所知,因此您无法轻松使用C语言中的C++对象.常见的技术是在"externed"函数中操作C++对象.


Mic*_*urr 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
Run Code Online (Sandbox Code Playgroud)

你可以做的是有一组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
Run Code Online (Sandbox Code Playgroud)

那么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
Run Code Online (Sandbox Code Playgroud)