호기심이 많은 사람은 똑 같은 걸 보고도 더 많은 것을 배울 수 있습니다. 이 경우는 개발자에게도 마찬가지 입니다. 함수 원형에 사용된 인자의 종류를 토대로 다음과 같은 의문을 품는 것은 함수를 사용하는데 큰 도움을 줍니다. 더불어 함수를 잘못된 방식으로 사용하는 것을 방지해 줍니다.
입력 – 과연 무슨 값을 전달할 수 있는가?
일반적으로 문자열, 정수, 포인터, 기호화된 값이라는 네 가지 종류의 입력 형태가 존재합니다. 파일 이름과 같은 것은 문자열이 될 것이고, 버퍼의 크기를 전달하는 인자는 정수에 해당합니다. 이 두 가지 값은 자신이 적합한 값을 지정해서 넘겨야 합니다. 포인터가 입력 인자인 경우는 주로 구조체로 다량의 정보를 함수에게 공급하는 경우입니다. 이 경우에는 구조체의 각 필드의 의미와 지정할 수 있는 값을 꼼꼼히 살펴보아야 합니다. 더불어 이 정보를 NULL을 사용해서 생략 가능한지도 체크해야합니다. MSDN에 NULL로 지정해도 된다는 문구가 없다면 *절대로* 해당 정보를 생략해서는 안됩니다. 끝으로 기호화된 값을 전달해야 하는 경우에는 반드시 레퍼런스에 명시된 기호들을 보고 어떤 값을 전달해야 할지를 신중하게 결정하도록 합니다. 무작정 0을 지정하는 습관은 좋지 않습니다.
출력 – 이 출력 버퍼의 크기는 얼마인가? NULL을 지정할 수 있는가?
윈도우 API가 출력 버퍼에 접근하는 방식은 크게 두 가지 입니다. 고정 크기와 가변 크기가 그것입니다. 고정 크기의 출력 버퍼는 주로 구조체를 출력 버퍼로 사용하는 경우입니다. 이 방식의 특징은 크기가 고정이기 때문에 별도로 출력 버퍼의 크기를 지정하지 않는다는 점 입니다. 가변 크기의 대표적인 형태는 문자열 버퍼를 사용하는 경우입니다. 이런 경우에는 반드시 함수 인자에 출력 버퍼의 크기를 지정하는 항목이있습니다. 가변 크기 출력 버퍼를 사용하는 경우에는 크게 두 가지를 잘 살펴야 합니다. 하나는 버퍼 크기를 올바로 지정하는 것이고, 다른 하나는 버퍼가 부족한 경우에 처리 방식입니다. 대부분의 윈도우 API는 이 버퍼가 부족한 경우에 적절한 오류코드를 반환하도록 설계되어 있습니다. 따라서 해당 오류 코드가 반환된다면 버퍼를 늘려서 다시 함수를 호출하도록 작성해야 합니다. 여기에는 흔히 사용되는 두 종류의 패턴이 있습니다. 하나는 0 크기 버퍼를 넣어의 질의를 한 다음 버퍼 크기 만큼 할당해서 함수를 호출하는 방식입니다. 다른 하나는 고정 크기 버퍼를 넣어서 호출을 한 후 부족하다면 다시 할당해서 함수를 호출하는 방식입니다. 성능을 생각한다면 두 번째 방법이 더 좋다는 것을 알 수 있습니다.
다량의 출력 버퍼를 사용하는 함수들은 대부분 NULL을 통해서 해당 정보를 받지 않도록 지정할 수 있습니다. 하지만 이 또한 MSDN에 NULL로 지정해도 된다는 말이 없다면 절대로 NULL을 넘기지 마세요. 지금의 운영체제에서는 문제가 발생하지 않더라도 구식 운영체제에서는 오류가 뜰 수 있습니다.
일부 함수이긴 하지만 이중 포인터를 사용해서 함수가 직접 출력 버퍼를 할당하는 경우도 있습니다. 이 경우에 함수를 호출하는 쪽에서는 출력 버퍼의 크기에 전혀 신경을 쓰지 않아도 됩니다. 하지만 반대로 반환된 출력 버퍼를 해제하는 것에 신경을 써야 합니다. 해제에 관한 부분을 꼼꼼히 읽도록 합니다. 삭제를 해야 하는 것인지, 어떤 방식을 통해서 삭제를 해야 하는지를 기억하면 됩니다.
입출력 – 이 출력 버퍼의 크기는 얼마인가? NULL을 지정할 수 있는가? 함수 호출 전에 어떤 부분을 설정해 주어야 하는가?
기본적인 접근은 출력버퍼와 동일합니다. 한 가지 틀린 점이라면 함수 호출 전에 어떤 부분을 설정해야 하는지를 확실하게 이해하는 것 입니다. 윈도우 API가 입출력 방식을 사용하는 가장 흔한 형태는 운영체제에 따라서 다른 크기의 구조체를 사용하는 경우입니다. 따라서 대부분 구조체의 크기를 미리 지정하도록 설계되어 있습니다. 이 경우 가장 주의해야 할 점은 여러분이 어떤 구조체를 사용하고 있는지 정확하게 인지하는 것 입니다. 여러분이 사용하는 구조체가 하위 버전의 운영체제에서는 지원되지 않을 수 있습니다 (관련 삽질).
0 0