2009-05-08 6 views
13

DLL 파일에서 일부 기능을 숨기는 C API를 만듭니다.C 인터페이스의 핸들에 적합한 유형

내부적으로 모든 것이 C++이므로 대부분의 함수는 API 내부에서이 포인터에 직접 매핑되는 핸들에 대해 작동합니다.

내가 같은를 정의하는 핸들에 안전한 형태의 어느 정도 효율적으로 활용하려면 다음 작업을

난 단지 포인터로 사용하고 작업을 수행하기 때문에 실제로 어떤 장소에서 MyType1 또는 MyType2를 정의하지
typedef struct MyType1* MyType1Handle; 
typedef struct MyType2* MyType2Handle; 

api 내부에 실제 포인터 유형으로 캐스팅됩니다.

내 문제는 비주얼 스튜디오에서 CLR 프로젝트에서 내 라이브러리를 사용할 때이 작동하기 때문에 그것은 별거 아니이 warning: unresolved typeref token (token) for 'type'; image may not run.

http://msdn.microsoft.com/en-us/library/h8027ys9(VS.80).aspx

를 얻을 수 있다는 것입니다,하지만 전문가가 아닌 보인다.

나는 * 무효 사용 좋아하지 않는다 : 이것은 가능 그들이 실제로 같은 유형부터 MyType2Handle와 MyType1Handle을 원하는 함수를 호출 할 수 있습니다

typedef void* MyType1Handle; 
typedef void* MyType2Handle; 

.

내가 사용하지 않는 다른 방법이 잘 한 INT 년대와 포인터는 같은 크기를 가지고 일하는 것이이

typedef int MyType1Handle; 
typedef int MyType2Handle; 

같은 것입니다,하지만 항상 그런 것은 아닙니다 그리고 거기처럼 보인다 플랫폼 특정 포인터 크기의 정수를 얻는 절대 안전한 방법은 아닙니다. void *와 같은 유형 안전 문제가 있습니다.

해봤 또 다른 방법은 다음과 같이 그것을 할 수 있었다 : 빈 구조체 이후

struct MyType1{}; 
typedef struct MyType1* MyType1Handle; 

이 C에서 작동하지 않았다가 유효 C 코드입니다. 물론 더미 멤버를 사용하여 구조체를 확장 할 수는 있지만 더 나은 방법이 있어야합니다. 당신은 일반적으로 대부분의 호환 방법으로 유형의이 종류를 지정하려면 어떻게

:

그래서 제 질문은 아래로 비등?

답변

12

당신은 MS가 실제로 다음과 같습니다 WINAPI 핸들 (WINNT.H)의 정의 방법을 보면 : 그래서

#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name 

: 사실

struct HWND__ { int unused; }; typedef struct HWND__ *HWND 

들이 이것에 대한 매크로를 가지고있다. 이렇게하는 것이 일반적인 관행 인 것 같습니다. 불행히도 나는이 외에는 다른 제안을 할 수 없습니다. 이미 언급했는데, 어쨌든 도움이 되었기를 바랍니다.

+0

감사합니다. 적어도이 문제에 대해 가장 먼저 떠드는 사람이 아닌 것 같습니다. – Laserallan

+0

하나의 차이점은 공용 헤더에서 HANDLE 유형이 구체적인 유형을 참조한다는 것입니다. 가짜 구조체가 완전히 정의되었습니다. 물론, 구현시 파일을 포함 할 때 DECLARE_HANDLE을 다르게 정의합니다. – RBerteig

3

나는 그냥 소스 구조, 정의 선언 할 수는 없지만 생각 :

구조체 MyType1;

typedef struct MyType1 * MyType1Handle;

8

불투명 한 구조체를 사용하십시오. 이것은 C에서 라이브러리에 대한 인터페이스를 정의 할 때 많은 경우에 좋은 생각입니다. 모듈성이 향상되고 불필요한 세부 사항이 숨겨집니다.

JamieH가 말했듯이 JamieH는 구조체를 선언하여 (불투명 한) 구조체를 얻습니다. 불투명 한 구조체에 대한 포인터를 인수로 라이브러리 함수에 넣고 값으로 반환하는 것은 완벽합니다. 그러나 라이브러리 사용자는 크기와 내용이 알려지지 않았기 때문에 불투명 한 구조체의 객체를 생성하거나 수정할 수 없습니다.

C 표준 라이브러리 및 많은 다른 기술에서는 이미이 접근 방식을 사용하므로 익숙해야합니다. 정규 표현식은 FILE *을 사용합니다 : fopen()은 구조체를 생성하고 초기화하며 포인터를 반환합니다. fclose()이 정리되고 해제되고 다른 모든 I/O 함수는 FILE *에서 전달 된 컨텍스트를 가져옵니다.

+0

typedef에서 포인터를 숨기면 종종 문제가 생깁니다 (프로그램이 포인터를 사용하지 않는 것처럼 보이더라도 포인터에 대해 뭔가를 말하는 오류 메시지를 말하거나 그 반대). 그래서 위의 HWND 접근법은 실제로 추천 할 수 없습니다. struct-definition-not-exposed 작품이 더 잘 작동합니다. C++의 경우 클래스 정의가 작동하도록 만들어야하기 때문에 "d- 포인터"접근 방식이 가장 효과적입니다. – user502515

관련 문제