문제

다음과 같은 선언이 있는 타사 라이브러리를 사용하고 있습니다.

typedef struct {} __INTERNAL_DATA, *HandleType;

그리고 저는 다음과 같은 수업을 만들고 싶습니다. 핸들 유형 생성자에서:

class Foo
{
    Foo(HandleType h);
}

없이 정의하는 헤더를 포함하여 핸들 유형.일반적으로 이러한 유형을 전달 선언하면 되지만 이에 대한 구문을 파악할 수 없습니다.나는 정말로 다음과 같은 말을 하고 싶다:

struct *HandleType;

하지만 GCC에서는 "* 앞에 예상되는 식별자"라고 표시됩니다.내가 볼 수 있는 유일한 해결책은 다음과 같이 수업을 작성하는 것입니다.

struct __INTERNAL_DATA;
class Foo
{
    Foo(__INTERNAL_DATA *h);
}

그러나 이는 라이브러리의 내부 세부 사항에 따라 달라집니다.즉, 구현 세부 사항인 __INTERNAL_DATA라는 이름을 사용합니다.

__INTERNAL_DATA(라이브러리 구현의 일부)를 사용하지 않고 HandleType(공개 API의 일부)을 전달 선언하는 것이 가능할 것 같습니다. 방법을 아는 사람이 있나요?

편집하다:제가 찾고 있는 내용에 대한 자세한 내용을 추가했습니다.

도움이 되었습니까?

해결책

업데이트:

FOO의 구현 .cpp에서 그것을 사용하고 있지만 foo의 헤더 .h에 포함시키지 않기를 원합니다. 어쩌면 내가 너무 멍청해질까요? :)

예, 당신은 :) 선언 선언을 계속하십시오.

Handletype이 인터페이스의 일부인 경우이를 선언하는 헤더가 있어야합니다. 그 헤더를 사용하십시오.

당신의 문제는 여전히 모호한 문제입니다. 당신은 당신이 할 수없는 것을 보호하려고 노력하고 있습니다.

클라이언트 라이브러리에 다음 줄을 추가 할 수 있습니다.

typedef struct INTERNAL_DATA *HandleType;

그러나 이름/구조가 변경되면 일부 캐스팅 성가신 일 수 있습니다.

템플릿 시도 :

template <class T>
class Foo
{
    Foo(T h);
};

선언은 괜찮습니다. 포인터 나 참조를 사용하려면 클래스 만 필요합니다 (__INTERNAL_DATA) 범위의 선언. 그러나 멤버 함수 또는 객체를 사용하려면 헤더를 포함해야합니다.

다른 팁

유형이 제 3 자 도서관에 있으면 선언 선언의 큰 이점 (헤더 변경으로 인한 재건축)이 효과적으로 손실됩니다.

컴파일 시간 (상당한 헤더)이 걱정된다면 아마도 컴파일 된 헤더에 배치하거나 라이브러리에서 관련 헤더를 포함시킬 수 있습니다.

예를 들어 많은 라이브러리 헤더가 모양이 생겼습니다

// library.h
#include "Library/Something.h"
#include "Library/SomethingElse.h"
 typedef struct {} __INTERNAL_DATA, *HandleType;

이와 같이 정의 된 경우 (한 줄에 모두) __ 인 내부 데이터는 핸들 타입만큼 공개 인터페이스의 일부입니다.

그러나 나는 생각하지 않습니다 __INTERNAL_DATA 실제로 존재합니다. 아마도 핸들 타입은 실제로 (내부적으로) int 일 것입니다. 이 홀수 정의는 int와 같은 크기가되도록 정의하는 방법 일 뿐이므로 컴파일러가 핸들 타입을 전달 해야하는 int를 전달하려고하면 오류가 발생합니다. 도서관 공급 업체는 쉽게 "int"또는 "void*"로 정의했을 수 있지만 이런 식으로 우리는 어떤 유형의 검사를받습니다.

따라서 __INTERNAL_DATA 컨벤션 일뿐 아니라 변화하지 않을 것입니다.


업데이트 : 위의 것은 약간의 정신 버프였습니다 ... 좋아요, __INTERNAL_DATA 확실히 존재하지 않습니다. 우리는 사실을 위해 이것을 알고 있습니다. 보다 빈 구조물로서의 정의입니다. 제 3 자 라이브러리는 "C"외부 연결 (이름 관리 없음)을 사용한다고 생각합니다. typedef를 복사하면 괜찮을 것입니다.

라이브러리 자체 내부, 핸들 타입 ~ 할 것이다 완전히 다른 정의를 가지고 있습니다. 아마도 int, 아마도 "struct mystruct {.......} *".

당신이 정말로, 정말로, _internal_data를 발신자에게 노출시키고 싶지 않다면, 당신의 유일한 선택은 사용하는 것입니다. typedef void* handletype; 그런 다음 라이브러리 내부에서 *핸드 레타 타입의 전체 구현 변경을 포함하여 원하는 모든 것을 수행 할 수 있습니다.

실제 데이터에 액세스하기 위해 도우미 기능을 작성하십시오.

inline _INTERNAL_DATA* Impl(HandleType h) {
    return static_cast<_INTERNAL_DATA*>(h);
}

무엇을 하려는지 잘 모르겠지만 다음은 실제 헤더 파일을 포함하지 않고도 작동합니다.

// foo.h
class Foo
{
    public:
    template<typename T>Foo(T* h) { /* body of constructor */ }
};

주의하세요. 여전히 public 멤버에 액세스할 수 있어야 합니다. __INTERNAL_DATA 생성자의 본문 내에서.

편집하다: James Curran이 지적했듯이 __INTERNAL_DATA 구조체에는 멤버가 없으므로 위와 같이 문제 없이 사용할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top