2016-06-21 3 views
0

파일 설명자를 사용하는 라이브러리를 작성하는 경우 더 높은 계층 코드를 사용하기 위해 lib_init()에서 언제 반환해야합니까? lib_do_stuff() 호출로 전달합니다. , 그리고 언제 그것을 C 라이브러리의 private "member"로 정적 전역으로 .c 파일에 남겨 둘 수 있습니까?C.의 파일 설명자 대 정적 전역 대

내 라이브러리 사용자가 파일 설명자를 제어하거나 액세스 할 필요가 없다고 생각하면 C++과 마찬가지로 그냥 그대로 둘 수 있습니까? private입니까?

어떤 방법 으로든 단점이 있습니다.

+1

일반적으로 정적 전역 변수를 사용하지 않아야합니다. 대신 필요한 모든 변수를 멤버로 포함하는 "블랙 박스"구조를 만들고 초기화 함수에서 포인터를 반환하는 것이 좋습니다. 예를 들어 C 표준 I/O 기능과 매우 유사합니다. 'fopen'은 정의되지 않은'FILE' 구조체에 대한 포인터를 리턴합니다. –

+0

C에서 멤버로 필요한 모든 내부 변수를 어떤 방법으로 정의 할 수 있습니까? 나에게 이것은 번역 단위 전체에서 사용할 수 있지만 외부에서 가져올 수 없음을 의미합니다. 꽤 정적 인 전역 변수입니다. 맞습니까? – justynnuff

+0

"블랙 박스"구조에 대한 좋은 점은 API 사용자가주의 할 필요없이 걱정없이 새로운 멤버를 추가하거나, 오래된 것을 삭제하거나, 기존의 변경 사항을 적용 할 수 있다는 것입니다. –

답변

3

예제를 통해 내 제안을 확장하십시오.

라이브러리에는 최소한 두 개의 (적어도) 헤더 파일이 필요합니다. 라이브러리 사용자가 포함하는 공용 폴더와 라이브러리 원본 파일에만 포함되는 개인 파일이 필요합니다.

대중은 당신이 모두 공공 및 민간 헤더 파일 및 사용을 포함하여 라이브러리 소스 파일에서 다음

#pragma once 

struct internal_structure 
{ 
    int fd; 
    // Other members as needed 
    ... 
}; 

// Possible function prototypes of private functions 

전용 헤더 파일을 가지고

다음
#pragma once 

// This is all that is needed to declare pointers to the internal structure 
typedef struct internal_structure STRUCTURE; 

// The public API of your library 
STRUCTURE *lib_init(void); 
void lib_cleanup(STRUCTURE *s); 
... 

같은 수 블랙 박스 구조에 대한 STRUCTURE :

#include <stdlib.h> 
#include "public.h" 
#include "private.h" 

STRUCTURE *lib_init(void) 
{ 
    STRUCTURE *s = malloc(sizeof *s); 
    s->fd = open(...); 
    // Other initialization 
    ... 
    return s; 
} 

void lib_cleanup(STRUCTURE *s) 
{ 
    // Other cleanup 
    ... 
    close(s->fd); 
    free(s); 
} 

그런 다음 라이브러리의 사용자는 공공 헤더 파일을 포함하고 잘 정의 된 API 사용

#include "public.h" 

int main(void) 
{ 
    STRUCTURE *s = lib_init(); 
    ... 
    lib_cleanup(s); 
    return 0; 
} 

공공 기능 모두 유사 해당 인수, 일반적으로 자신의 첫 번째 인자의 하나로서 STRUCTURE *를 취해야을 lib_cleanup 기능. 그런 다음이 함수는 원하는 방식으로 구조와 멤버를 사용할 수 있습니다.

+0

잠깐, 이제 각 소스 라이브러리 파일에 대해 두 배의 헤더 파일이 생겼다. 누군가가 사용할 수있는 헤더 파일에 "// 가능한 개인 프로토 타입 함수 프로토 타입"을 넣는 것이 좋겠다. 포인트. 사용자가 내 내부 변수에 액세스 할 수 있습니다. 어쩌면 나는 너무 많은 웹 응용 프로그램에서 일하고 있었기 때문에 나는 잘못된 생각에 빠졌지 만, "개인 회원"을 갖고 싶다는 것을 암시 할 때 나는 복잡한 코드를 작성하는 것이 아닙니다. 보안을 유지합니다. – justynnuff

+0

@justynnuff 예, 이전에 비해 두 배 많은 헤더 파일이 있지만 소스 파일 당 하나가 아닌 총 *** 개의 헤더 파일이 두 개 있습니다. 아니면 모든 라이브러리 소스 파일에 두 개의 헤더 파일을'# include '해야한다는 뜻입니까? 그렇다면 예. 그러나 그것은 IMO를 지불하는 작은 가격입니다. 특히 그것이 유일한 단점이라면 생각할 수 있습니다. –

+0

@justynnuff 또한 개인 헤더 파일을 설치하지 않고 *** 개인 ***로 유지합니다. 이것은 매우 일반적인 패턴입니다. "보안을 통해 보안이 유지됩니다."(적어도 오픈 소스가 아닌 경우 - 라이브러리 소싱). 코드 자체는 전체 구조를 공개하는 것보다 복잡하지는 않습니다. 이는 또한 매우 일반적입니다. 그리고 그것은 라이브러리 코드를 재진입 가능하게하는 가장 좋은 방법 중 하나입니다. 여러 스레드가 각각 라이브러리에 대해 별도의 "핸들"을 가질 수있게합니다. –