Win32 개발환경에서 VC++을 사용하면 디버그 모드에서 TRACE라는 매크로를 사용하여 디버그 결과창에 디버깅중 점검해야 할 내용들을 쉽게 볼 수 있도록 화면에 찍어줄 수 있는데, MFC를 사용하지 않거나 릴리즈 모드에서도 이걸 사용하고 싶을때 활용하는 방법..

우선 www.sysinternals.com 사이트에 가서 DebugView 라는 프로그램을 다운로드 받는다.. 이 프로그램은 디버그 결과창에 나오는 내용을 볼 수 있도록 해주는 어플리케이션인데, 디버그로 빌드가 되었건 릴리즈로 빌드가 되었건 상관없이 디버그 결과창에 찍히는 문자열들을 보여준다.. 릴리즈로 실행시에는 VS의 디버거로 실행되지 않으니 디버그 결과창을 볼 수 없으니 이 프로그램이 필요하다.. 물론, 디버그 모드로 빌드된 어플리케이션도 느리고 덩치큰 디버거와 함껫 실행시키는 것 보다 이 어플리케이션으로 확인해보는게 편한 경우도 많으므로 꽤 유용한 프로그램이다.. 이런 어플리케이션은 열심히 사용을 해줘야 한다..

TRACE 매크로는 디버그로 빌드된 경우만 동작하도록 작성되어 있으므로 TRACE 매크로 소스를 수정해서 사용하는 방법이 하나가 있겠고, TRACE 매크로 소스를 보고 릴리즈에서도 동작하도록 내가 만들서 쓰는 방법이 있다..

이와 같은 욕구는 이미 다른 개발자들도 가지고 있었을 것이고, 인터넷을 뒤져보면 아래와 같은 함수를 찾을 수 있는데, 릴리즈 모드 및 MFC를 사용하지 않는 Win32 API만 사용해야 하는 경우에 사용할 수 있다.. (나 같은 경우는 심심풀이로 Win32 게임을 만들면서 사용을 하려고 찾았었는데, 아직도 게임을 MFC로 만들면 안된다는데는 공감을 못하고 있다.. 흐흐흐.. 그때 찾은 출처를 남겨놨어야 하는데, 암튼 어디서 찾았는지 지금은 모르겠고, 다시 찾기는 좀 귀찮고.. 암튼 확실한건 내가 작성한 소스는 아니다..)

#include "stdio.h"

void Trace(char* szFormat, ...)
{
    char szTempBuf[2048] ;
    va_list vlMarker ;

    va_start(vlMarker,szFormat) ;
    vsprintf(szTempBuf,szFormat,vlMarker) ;
    va_end(vlMarker) ;

    OutputDebugString(szTempBuf) ;
}
이제 준비가 다 되었으니 TRACE를 쓰고 싶은 경우에 위의 함수를 사용하고, 위에서 설명한 어플리케이션을 띄워두면 된다.. 물론, 불필요한 코드가 호출되고 링크되는 것이 영 눈에 거슬린다면 매크로를 사용해서 디버그인 경우만 포함되도록 컨디셔널 컴파일 구성을 하면 되겠다..

보는 바와 같이 C 언어를 알면 해결할 수 있는 함수들로 구성되어 있고 모르는 API는 OutputDebugString 하나 뿐이다.. 의외로 이 API가 디버그 모드에서만 동작하는 것으로 아는 사람들이 많은데, 이름만 보고 섵부른 판단은 금물이다.. 궁금하면 직접 해보면 되는데, 사실 이런 궁금증을 가지는 사람도, 직접 궁금증을 해결하기 위해 행동하는 사람도 비교적 적은 것 같아 아쉽다..

프로그래밍 뿐만 아니라 무슨 일을 하던, 이건 이럴거야 라고 선입견을 가지기 전에 정말로 그런지 약간의 시간을 들여 확인을 해보면 많은 도움이 될 것 같다는 생각이 든다.. 아마, 이 함수는 많은 개발자들이 알고 있거나 이미 사용하고 있겠지만, 역시나 또 많은 개발자들이 이렇게 활용하는 방법이 있을 거라는 것 조차 모르고 넘어가고 있는 것 같아 (릴리즈에서는 디버그 문자열을 확인할 방법이 없네.. 걍 디버그로 하자.. 이런 자세.. 음, 좋지 않다..) 기록을 남겨본다..

물론, 나 역시 여러 상황에서 위와 같은 태도를 보이는 경우가 많긴 하지만 스스로 그러한 것들을 깨려고 노력할때 명랑 코딩 사회 건설에 도움이 되지 않을까 싶다.. 우선 명랑 코딩 사회 건설을 위해 프로그래밍은 3D라는 이야기 부터 우리 입에서 없애도록 하자.. 그러기 위해 오늘도 열심히 실력 연마를 위해 힘 내자구~
 
 
 
===================================================
실제 적용 - 1
===================================================
Visual C++에서 API 등 MFC가 아닌 프로그램을 작성할 때 TRACE 매크로 처럼

Output 창에 값을 출력하려면 다음과 같은 매크로를 작성하여 사용하면 된다.

파일에 기록하는 것도 유사하게 작성하면 되겠다.


**


#include <windows.h>

#include <stdio.h>


#ifdef _DEBUG

#define TRACEf                Tracef

#else

#define TRACEf                ((void)0)

#endif


#ifdef _DEBUG

#define MAX_MSG_SIZE          1024           // 1K 넘는건 보내지마! -_-x


void TRACEf(const char *szString, ...)

{

        static char szBuffer[MAX_MSG_SIZE];

        va_list argptr = NULL;


        va_start(argptr, szString);

        vsprintf(szBuffer, szString, argptr);


        OutputDebugString(szBuffer);


        va_end(argptr);

}

#endif


 

**


사용은 TRACE 매크로처럼 원하는 곳에서


**


TRACEf("s = %lf | t = %lf | u = %lf\n", s, t, u);


**


이렇게 하면된다. 당연히 릴리즈 모드일 때는 제외된다.


...


===================================================
실제 적용 - 2 : 파일로 작성
===================================================
void Global_WriteLog(const char* msg ...)
{
 SYSTEMTIME st;
 GetLocalTime(&st);

 char szCurTime[100] = {0, };
 _stprintf(szCurTime, "[%04d/%02d/%02d %02d:%02d:%02d.%04d]   ",
    st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

 TCHAR szLogPath[MAX_PATH] = {0, };
 wsprintf(szLogPath, "%s\\PTCAgent.log", g_szClientLogPath);
 g_fpLog = fopen(szLogPath, "a+");
 fprintf(g_fpLog, szCurTime);

 va_list ap;
 va_start(ap, msg);
 vfprintf(g_fpLog, msg, ap);
 fclose(g_fpLog);
}

블로그 이미지

요다할아범

,
일단 namespace는 중대형 프로젝트에서 타사 라이브러리를 자주 가져다 쓰는 경우 곧잘 발생하는 이름 충돌 문제를 해결하기 위해 도입됐습니다. 도입되기 전까지만해도 쓰자파와 쓰지말자파간에 입씨름이 대단했었으나, 결국 표준 라이브러리에 이름공간이 적용됨으로써 일단락 됐죠. 이후 개발되는 모든 언어에는 아예 이름 공간을 안쓰면 프로그램이 안되는 것들도 있습니다. 왜 그럴까요? 정말 윗분들 처럼 쓸데 없는것이라면.. 그냥 없애버리는게 나을텐데..?

namespace가 쓸데없다라고 말하는 사람들의 대부분은 대형 프로젝트를 경험해보지 못한 사람입니다. 대형 프로젝트를 경험했더라도, namespace 분할을 적절하게 하지 않았기 때문에 거추장스럽게만 느껴지는 경우겠죠.

-----------------

현대의 프로그램 세계는 모든것을 자체 개발하기엔 너무 덩치가 커졌습니다. 따라서 몇몇 라이브러리들은 구입해 사용하게 되는 경우가 많이 있는데요. namespace가 없는 A사와 B사의 라이브러리에 Tree라는 이름이 다음과 같이 나와있다고 해봅시다.

A사의 라이브러리중에
struct Tree {};

B사의 라이브러리중에
int Tree;

두개의 라이브러리는 호환되지 않는 이름의 충돌로 인해 컴파일이 안됩니다. 쉽게 말하자면, A사의 라이브러리와 B사의 라이브러리는 절대! 같이 쓸수 없는 라이브러리가 되는 것입니다.

이전에는 대개 라이브러리 함수 이름 앞에 특정한 패턴을 붙여서 이런 문제를 해결했죠 예를들어 acorpTree (A사의 Tree라는 뜻) 뭐 이런식으로요.. 그렇지만, 이런 경우 거의 대부분 읽기 어렵고 지저분한 소스를 만들어 내게 됩니다. 정리가 안되죠.

만약 A사와 B사가 namespace를 잘 정의해서 라이브러리를 구현했다면, 이런 문제를 깨끗하게 해결해 줍니다.

------------------

그럼 어떻게 namespace를 구현하느냐..
구현은 간단합니다. namespace로 정의할 것들을 블럭으로 묶으면 됩니다.

namespace A
{
struct Tree {};
}

namespace B
{ int Tree; }

-------------------

사용하는 측에서는 다음중 하나를 선택해 쓰면 됩니다.

1. using namespace A;
(의미 : 현재 소스 코드에 A사 라이브러리만 쓰이는경우, 이름충돌이 예상되지 않으므로, A에 있는 모든 이름들을 현재 소스의 범위내에 가져온다)

2. using A::Tree;
(의미 : 현재 소?코드에 A사와 B사의 라이브러리가 동시에 쓰이는데, 현재 블럭에서 사용할 Tree는 A사의 Tree 구조체이다)

3. B::Tree = 10;
(의미 : 현재 소스 코드에 A사와 B사의 라이브러리가 동시에 쓰이는데, 현재 블럭에서 두 회사의 라이브러리가 모두 섞여 쓰이므로 명시적으로 이름을 정해준다)

--------------------

이외에도, 이름공간에는 몇가지 까다로운 주의사항 및 고급 사용기법들이 있지만, 현 레벨에서는 이 정도로 충분하다고 봅니다.

윗분들의 답변을 보고.. 한심하다는 생각이 들어서 잔소리 좀 하고 가겠습니다. 우선 남들이 안쓰니깐 쓰지말라는건 말이 되지 않습니다. 전 오히려 namespace를 (적절히 잘) 쓰는 소스코드를 더 많이 봐왔는데요????

또, 어려운 소스를 쓰는 사람은 무조건 잘난척 하는 사람입니까? 천만에요. 그 소스를 만든 사람이 정말 잘난척을 하고 싶었는지의 여부는 물어보면 압니다. 잘난척 하기 위해 소스를 어렵게 만든 사람들은 그 용도를 정확히 알지 못합니다. 꼭 써야할 곳에 써야 하는데, 그러질 못하죠.

그런 잘난척(?) 하기위해 무조건 가져다 쓰는것도 문제가 됩니다. 불필요한 코딩 오버헤드가 발생하는데다, 오작동 할 우려가 크기 때문에요..

----------------------------

namespace가 어떻게 쓰일때 어떤 장/단점을 가지는지 명확히 판단하시고 쓰세요. 비단 namespace 뿐만 아니라, 다른 어떤 기술들도 마찬가지입니다.

** 우선 코어 엔진이나 라이브러리 개발자라면 namespace를 사용해 프로그래밍 하는 습관을 들이십시요. 물론 우리나라엔 게임 엔진을 파는 경우가 거의 없으니 해당사항은 없겠지만요.

** 반대로 그런 경우가 아니라고 하더라도, namespace의 사용법은 정확히 알고 있어야 합니다. 우리보다 뛰어난 프로그래머가 만들어 공개한 좋은 소스를 namespace를 몰라서 못쓴다면 좀 억울할테니까요..

잘쓰면 약이되고 잘못쓰면 독이 된다는 말씀 아시죠? namespace도 마찬가지입니다. 어떨때 왜 써야 하는지, 어떨때 왜 쓰지 말아야 하는지, 자꾸 생각하는 프로그래머가 되어야 합니다.

한 몇년 그만그만한 프로그래머로 지내다 결국 포기하는 사람들을 수도 없이 보아 왔습니다. 반대로, 정말 뛰어난 분들도 수없이 보아왔구요.. 그둘의 차이는, 편견없이, 솔직하게, 지적인 호기심을 가지고 사는 사람이냐 아니냐의 차이입니다. 부디 분발하셔서 좋은 프로그래머가 되시길 바랄께요.. 그럼.. 
블로그 이미지

요다할아범

,
쓰는게 3종류로 알고 있는데

1.중국 입국 신고서
2.입국 검역신고서
3.세관 신고서

쓰는 부분은 모두 영문으로 표기된 곳에 쓰시면 되는데

잘 모르시면 옆자리분 것 컨닝하면 됩니다. 이름까지 컨닝하면 안돼구요.

이거 쓰는것 어디 있는 걸루 아는데 주소는 잘 모르겟고


돌아올때 쓰는 것은 모두 한글이 있어서 컨닝안해도 돼요.

아마 중국 입국신고서, 출국신고서, 세관신고서 일겁니다.

입국신고서와 세관 신고서 중 주황색은 중국 입국 하실때 공항 입국심사대에서 제출하면 되고 출국신고서와 세관신고서 중 파란색은 보관하고 계시다 시간날때 작성하시고 중국 출국할때 출국심사대에 제출하면 됩니다.

작성내용은 모두 그리 어려운건 거의 없습니다. 출,입국 신고서는 영문이름과 여권번호, 타고온(갈) 항공 편명, 중국에서 머물렀던 주소 정도면 됩니다.


샘플이니 참고하세요~





<출처:   http://www.hanatour.com/asp/travelinfo/if-14000.asp?country_code=CN&state_code=&city_code=&alldetail_code=NG03N0CN0001&popup_yn=N >



블로그 이미지

요다할아범

,

1.regedit.exe 를 시작한다.
2.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services key로 이동한다.
3.지우고 싶은 서비스의 key를 선택한다.
4.Edit 메뉴에서 Delete를 선택한다.
5. "Are you sure you want to delete this Key" 메시지가 나오면 Yes를 선택한다.
6.regedit를 종료한다.


 

블로그 이미지

요다할아범

,
2018.11.05 Update
Windows 7, Windows 10에서 바로 이용할 수 있는 REG 파일 Upload --> 

Disable-ZIP-CAB-Compressed-Folders.reg

적용 후 재부팅!

===================================================================


XP 탐색기에서 ZIP 폴더를 없애려면 두가지 방법이 있는데

방법.1

시작버튼 -> 실행을 선택한 다음...

regsvr32 /u zipfldr.dll 이라고 쓰고 엔터...

복구는 regsvr32 zipfldr.dll 으로 하면 됩니다.


방법.2

regedit에서

zipfldr.dll로 검색해서 지워주면

껐다 켜도 ZIP 폴더 작동하지 않습니다.




----------------------------------------------------------------------------------------
윈도우 7 의 경우

1. 시작 메뉴 - 파일 검색 부분에서 regedit를 쓰고 엔터.

2. UAC 가 뜨면 확인을 누르거나, 사용자 계정에서 사용자 계정 컨트롤 부분을 꺼준다.

3. zip 폴더 비활성화
A) 해당 레지스트리 위치로 이동한다.
HKEY_CLASSES_ROOT\CLSID\{E88DCCE0-B7B3-11d1-A9F0-00AA0060FA31}

사용자 삽입 이미지


B) 해당 폴더를 우클릭하여 사용권한 메뉴로 들어간다.

C) 5번째로 이동하여 진행할것.
4. CAB 파일 비활성화 
NOTE: You will also need to step 3 as well to disable CAB folders.
A) 해당 위치의 레지스트리 폴더로 이동한다.
HKEY_CLASSES_ROOT\CLSID\{0CD7A5C0-9F37-11CE-AE65-08002B2E1262}

사용자 삽입 이미지


B) 해당 폴더를 우클릭 후 사용권한 메뉴로 들어간다.
5. 고급 버튼을 누른다.  

사용자 삽입 이미지


6. 소유자 탭에 들어가서 현재 사용중인 계정을 클릭하고 확인을 누른다. ( 관리자 계정이 아니면 레지스트리 변경이 안되므로.. 일반 계정으로는 해당 단계를 진행하지 못합니다. ) 

7. 유저 및 어드미니스터의를 선택하여 모든 권한 에 체크를 하고 확인을 누릅니다.  

사용자 삽입 이미지


8. 해당 레지스트리 폴더(cab 또는 zip 레지스트리 폴더) 를 삭제합니다.  


블로그 이미지

요다할아범

,