플랫폼 독립적인 코드 작성 Programming

윈도우용으로 작성한 코드를 리눅스용으로 포팅할 일이 생겼는데, 다행히 ACE 기반으로 작성된 코드라 쉽게 포팅 할 수 있었습니다. 포팅중에 정리해둔 것을 옮겨봅니다.

대소문자의 명확한 구분
파일을 지칭할때 윈도우와 달리 리눅스는 대소문자를 명확하게 구분합니다. 윈도우에서 그냥 넘어갔던 코드가 문제가 생길수 있습니다. 대부분 include에서 문제가 발생합니다.
  • "Stdafx.h" -> "stdafx.h"
  • ace/os_ns_string.h -> ace/OS_NS_string.h
ACE 타입의 사용
gcc에는 tchar.h 가 없기때문에 TCHAR를 모두 ACE_TCHAR로 변경했습니다.
  • TCHAR ->ACE_TCHAR
  • _T("text") - > ACE_TEXT("text")
또하나 유의할점은 TCHAR는 _UNICODE define 유무에 따라 char/wchar이 결정되지만 ACE_TCHAR는 ACE_USES_WCHAR define에 따라 결정됩니다.

_s 함수들
vc에서는 strcpy_s와 같이 _s가 붙은 함수의 사용을 권장하고 컴파일시에 경고메세지도 나옵니다. 하지만 gcc에는 없는 함수이기 때문에 그냥 strcpy함수 를 사용해야 합니다. 뒤에도 나오지만 ACE_OS::strcpy 함수를 쓰는게 가장 좋습니다. 설정에 따라 char/wchar로 switch되기 때문입니다. 그래도 C4996 warning은 피할수 없습니다. _CRT_SECURE_NO_DEPRECATE으로 끄는 수밖에 없습니다.

ACE 함수의 사용
ace/OS_NS_string.h, ace/OS_NS_stdlib.h, ace/OS_NS_stdio.h 에는 문자열과 io를 다루는 함수들이 있습니다. 그 함수들을 사용하면 ACE가 플랫폼과 char/wchar에 맞는 함수들을 호출해줍니다.

  • sprintf -> ACE_OS::sprintf
  • strcpy -> ACE_OS::strcpy
  • atoi -> ACE_OS::atoi
  • atof -> ACE_OS::atof
  • strcmp - >ACE_OS::strcmp
  • strtoul - > ACE_OS::strtoul
  • strlen - >ACE_OS::strlen
  • strcat -> ACE_OS::strcat
  • vsnprintf - >ACE_OS::vsnprintf
  • fopen - >ACE_OS::fopen
  • fread - > ACE_OS::fread

멤버함수 템플릿 특수화의 미묘한 차이
vc에서는 되는데, gcc에서는 inline으로 해결해야 하는 문제가 있더군요. 특정 상황에서 템플릿 멤버함수가 특수화가 되지 않는 현상이었습니다. 아마 부분 특수화 관련 이었던것 같은데, vc의 문제인지 gcc의 문제인지는 알수 없지만 반드시 체크해야 합니다.

GetTickCount() 함수
GetTickCount()는 리눅스에서는 gettimeofday()로 바꾸어주어야 합니다. 그냥 치환만 하면 되는건 아니고 받아오는 단위가 다르기 때문에 변환도 필요합니다. 아래와 같이 만들어서 사용했습니다.
unsigned int  GetTick()
{
#ifdef WIN32
    return GetTickCount();
#else
    timeval tick;
    gettimeofday (&tick, 0);
    return (tick.tv_sec*1000 + tick.tv_usec/1000);
#endif
}

InterlockedCompareExchange 함수
ACE에는 이 함수에 대응하는 함수가 없습니다. 이 외의 interlocked 계열 함수들은 모두 있습니다만 유독 이함수만 없습니다. 그냥 lock걸고 비교하는 방식으로 변경해야합니다.



덧글

  • coder 2009/11/12 03:50 # 삭제 답글

    없다면 만들어서 쓰면 되지 않을까요? 아래처럼..
    (prefix로 _를 붙인 이유는 api 보단 vs2008-style intrinsics linkage 가 더 좋지 않을까 해서..)

    static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
    {
    return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
    }

    출처: ReactOS
  • 자바워크 2009/11/12 17:52 #

    gcc에는 이런게 있군요. 좋은 정보 감사합니다. (__)
    검색을 좀 해보니 cpu에 따라 동작하지 않는 경우도 있나 봅니다.
    그래서 ACE에는 넣지 않은 모양이네요.
댓글 입력 영역