2012-09-22 3 views
0

코드를 설명합니다 다음과 같은 상황은 내가가 발생했습니다네임 스페이스와 C++/C 혼합 헤더

#ifdef __cplusplus 
namespace ns 
{ 
class pod 
{ 
    const short foo; 
    const char bar; 
public: 
    pod(short f,char b):foo(f),bar(b){} 
    char foobar(); 
}; 
} 
#else 
typedef struct pod pod; 
#endif 


#ifdef __cplusplus 
extern "C"{ 
#endif 

extern pod* pod_new(short f, char b);//BANG!!! 
extern char pod_foobar(pod* p); //BANG!!! 

#ifdef __cplusplus 
} 
#endif 

내가 네임 스페이스 ns 내부의 C 연동 기능을 넣을 수 없습니다, 또는 C 클라이언트가 자신의 정의를 찾을 수 없습니다 . 네임 스페이스에서 꺼내면 C++ 정의도 컴파일되지 않습니다. 왜냐하면 C++ FAQ Lite에서 배웠던 pod 솔루션 때문입니다. 이것은 단지 전 처리기 트릭입니다. 그리고 슬프게도,이 속임수는 네임 스페이스를 다룰 수 없었습니다.

은 내가 무엇을 해야하는 거? 모든 유형 안전을 제거하고 pod*void*으로 대체해야합니까? 아니면이 상황에 대한 더 좋은 해결책이 있습니까? 조언? 부디!

+0

을 나는이 다운 요리 예입니다 생각하지만'typedef' '; '를 놓친다 –

답변

3

난 그냥 기능 C에 대한

++에 대한 두 가지 선언을 줘야 할 것 :

extern "C" ns::pod* pod_new(short f, char b); 
extern "C" char pod_foobar(ns::pod* p); 

와 C에 대한 :

typedef struct pod pod; 
extern pod* pod_new(short f, char b); 
extern char pod_foobar(pod* p); 

그러나 이것은 당신을 만족하지 않는 경우에 대한 C++도 가질 수 있습니다. typedef

typedef ns::pod ns_pod; 
다음 C

typedef struct ns_pod ns_pod; 

및 10은

동일한 공통 기능 프로토 타입을 갖는다.

extern ns_pod* pod_new(short f, char b); 
extern char pod_foobar(ns_pod* p); 

편집 : 직접이 필드를 사용하거나 크기를 요구 아무것도 할 수 없었다 C에 있도록 C에서이 struct pod 또는 struct ns_pod는 불완전한 유형입니다. 불완전 유형에 대한 포인터와 void*의 차이점은 동일한 struct 포인터를 동일한 불완전 유형의 다른 struct 포인터에만 할당 할 수 있다는 것입니다.

typedef struct ns_pod2 pod2; 
ns_pod* q = pod_new(...); // valid 
ns_pod2* r = pod_new(...); // a constraint violation! (= compiler error) 

주장하고 싶은 경우 두 번째 것은 명시 적 캐스트가 필요합니다. 이것은 많은 C 프로그래머가 캐스트를 싫어하는 이유 중 하나입니다.

+0

하나의 정의 규칙을 망각시키지 않습니까? (당신은 C++을 위해'ns :: pod'와'C'를 위해서':: pod'를 정의합니다) – Lol4t0

+0

@ jens-gustedt 여러분의 모든 반응에 감사드립니다. 내 C++ 측 코드가이 혼합 된 헤더로 감추어지는 것을 원하지 않습니다. 그리고 너 또는 누군가가 ns : pod *와 C의 관계가 pod *를 어떻게 typedefed했는지 설명 해줄 수 있습니까? C++ 측에서 ns :: pod가 형식 검사를 유지하지만 C면에서 불완전한 구조체 이름이 실제로 의미가 있습니까? – Need4Steed

+0

@ Lol4t0, 아니요 정의가 하나 뿐이지 만 C는 정의를 전혀 볼 수 없습니다. C에서는 forward 선언 만 있고'struct pod' 또는'struct ns_pod'는 불완전한 타입입니다. –

0

내가 직접 알아 낸 :) nm으로 obj 파일의 기호를 확인합니다.

그것은 C++ 네임 스페이스는 C 연동과 기능에 아무런 영향이없는 것으로 나타났다 그러므로 나는 이런 식으로 위의 코드를 다시 작성할 수 있습니다 :

#ifdef __cplusplus 
namespace ns 
{ 
class pod 
{ 
    const short foo; 
    const char bar; 
public: 
    pod(short f,char b):foo(f),bar(b){} 
    char foobar(); 
}; 
} 


#else 
typedef struct pod pod; 
#endif 


#ifdef __cplusplus 
namespace ns{ 
extern "C"{ 
#endif 

pod* pod_new(short f, char b); 
char pod_foobar(pod* p); 
void pod_free(pod* p); 

#ifdef __cplusplus 
} 
} 
#endif 
관련 문제