2009-06-29 3 views
7

C에서 직접 C++ 객체로 작업하는 간단한 방법이 있습니까? 일부 클래스를 C++에서 C 또는 FFI (외부 함수 인터페이스)에 노출하려고합니다. 물론 , 나는 그런 물건을 쓸 수 있습니다 :C++ 코드 및 C?

class Foo{ 
.... 
}; 

void *make_foo(...){ 
Foo *ptr = new Foo(..) 

return static_cast<void *>(ptr); 
} 

.. 

int *foo_method1(void *fooptr, ...){ 
Foo *ptr = static_cast<Foo*>(fooptr); 
} 

을하지만 간단한 방법이있다?

+0

Lisp과 관련이 있는지 물어봐도 될까요? – Svante

+0

이것은 C++ 클래스를 Common Lisp에 노출시키는보다 일반적인 질문의 일부입니다. CFFI (또는 Lisp 구현에 종속적 인 FFI)입니다. –

답변

8

일반적으로 가장 간단한 방법입니다.

모든 C 래퍼 메서드에도 extern "C"을 사용해야 함을 기억하십시오.

7

거의 다 왔어. 독립 실행 형 함수 앞에 extern "C"을 붙이면 C++ 컴파일러의 name mangling이 해제됩니다. 예를 들어

는 :

extern "C" void *make_foo(...){ 
    Foo *ptr = new Foo(..) 

    return static_cast<void *>(ptr); 
} 
1

정말 그것을 할 수있는 간단한 방법이 아니다. SWIG을 사용하여 데이터 집합보다 많은 사용자 정의 형식을 사용하여 다른 언어로 이동할 수 있지만 C로 변환하면 C의 개체 개념을 사용해야합니다.

1

Verrazano/Fetter을 사용하여 C++ 코드의 CFFI 바인딩을 생성 할 수 있습니다. 하지만 GCC-XML이 필요하며 이식성이 확실하지 않습니다.

1

가능한 경우 클래스가 구조체에서 파생되도록하십시오. 그런 다음 C 코드에서이 구조체에 대한 포인터를 사용할 수 있습니다

// C++ code 
extern "C" struct Cfoo {}; 
extern "C" struct Cbar {}; 

class foo : public Cfoo {}; 
class bar : public Cbar {}; 

// C API 
extern "C" { 
    struct Cfoo; 
    struct Cbar; 
} 

그것은 그러나 GCC는 적어도 다른 종류의 포인터 사이의 변환에 대해 경고, 엄격 오류가 아니다. 당신이 상속 할 수없는 경우

void foo (void) { 
    struct Cfoo * pf; 
    struct Cbar * pb; 
    pf = pb;  // gcc warns 
} 

후 비슷한 아이디어를 사용하지만 C 구조 저장소에게 C++ 객체에 대한 포인터를 가지고 있고, 또 단지 앞으로 C API의 구조를 선언

// C++ code 
class foo {}; 
class bar {}; 

extern "C" struct Cfoo { foo * pFoo; }; 
extern "C" struct Cbar { bar * pBar; }; 

// C API 
extern "C" { 
    struct Cfoo; 
    struct Cbar; 
} 

여기서 단점은 Cfoo 및 Cbar 객체의 수명을 관리해야한다는 것입니다.