기본 콘텐츠로 건너뛰기

2013의 게시물 표시

CRect와 &CRect와 LPCRECT

MFC 프로그래밍 중에 무척 황당한 경험을 했습니다. void CTestCRect::OnDraw(CDC* pDC) { CRect rect(50, 50, 300, 300); pDC->DrawText(_T("Test!!"), &rect, DT_WORDBREAK | DT_EDITCONTROL); rect.MoveToX(200); pDC->DrawText(_T("Test!!"), rect, DT_WORDBREAK | DT_EDITCONTROL); } 보통은 이와 같이 사용합니다. 그런데 뭔가 좀 이상하지 않나요? 네, DrawText()를 호출할 때 처음에는 rect의 주소를, 다음에는 그냥 rect를 전달합니다. 전혀 컴파일에 오류도 없고... 둘다 정상 작동합니다. 함수 원형을 살펴보면 CRect를 받는 자리에 LPRECT가 적혀 있는데, LPRECT는 (RECT 구조체의) 포인터입니다.(CRect와 RECT는 호환됩니다.) 그러니까 함수 원형만 놓고 보면 &rect로 전달하는 것이 맞습니다. 그런데 왜 rect로 전달해도 될까요? 그것은 CRect에 LPRECT에 대한 케스팅 연산자가 재정의 되어 있기 때문입니다. 그래서 LPRECT 자리에 CRect를 넣으면 CRect에 정의된 케스팅 연산자가 알아서 CRect의 주소를 반환합니다. 참고: MSDN - CRect::operator LPRECT() 클레스등에서 타입캐스트연산자 오버로딩

STL std::map 사용시 "이항 '[' : 왼쪽 피연산자로 'const std::map<_Kty,_Ty>' 형식을 사용하는 연산자가 없거나 허용되는 변환이 없습니다." 에러 해결법

다음의 코드를 봐주세요. class Test { /* 생략 */ Item* m_pSelectedItem; std::map<int, Item*> m_map; int Test::GetSelectedItemIndex() const; } int Test::GetSelectedItemIndex() const { for(int i = 0; i < 10; ++i) { if(m_pSelectedItem == m_map[i]) { return i; } } return -1; } 컴파일을 해보면 이상하게도 위에서 밑줄친 부분에 "이항 '[' : 왼쪽 피연산자로 'const std::map&lt;_Kty,_Ty&gt;' 형식을 사용하는 연산자가 없거나 허용되는 변환이 없습니다."라는 에러 메시지가 나타납니다. 한참을 해맸는데, 원인은 메서드를 const로 선언한 탓이었습니다. map의 [] 연산자는 const가 아니라서 const로 선언된 메서드에서 사용할 수 없습니다. (map[i]를 할 때, 없는 원소인 경우에는 NULL 객체를 삽입한다고 합니다.) 즉 오류를 해결하려면, "int Test::GetSelectedItemIndex() const "를 "int Test::GetSelectedItemIndex()"로 바꾸어 주시면 됩니다. 참고: * stl map쓰는데 에러가 납니다 * std::map 의 무서운 비밀 * std::map 레퍼런스

APM Setup의 PHP 버전 바꾸기

현재 APM Setup 7은 PHP 5.2가 기본적으로 설치가 되는데요. 저는  5.3이 필요했습니다. 검색을 통해 간단한 방법을 찾았습니다. 여기(PHP 다운로드 페이지) 로 이동합니다. 위 페이지에서 원하는 버전을 찾은 후, "VC9 x86 Thread Safe" 항목의 "Zip" 파일을 다운로드합니다. 받은 파일의 압축을 풉니다. APM Setup 모니터를 실행해서 아파치 서버를 멈춥니다. APM Setup이 설치된 폴더로 이동합니다. (제 경우에는 C:\APM_Setup) Sever 폴더로 이동합니다. 그러면 PHP5폴더가 보이실 텐데, 만약을 대비해서 해당 폴더의 이름을 PHP5_Backup 등으로 변경합니다. 위의 '3.'에서 압축을 풀어 나온 폴더를 Server 폴더로 이동 시킨 다음에 폴더의 이름을 PHP5로 바꿉니다. APM Setup 모니터에서 아파치 서버를 다시 시작합니다. 정상작동 하는지 확인합니다. (※ 만약 문제가 발생하는 경우에는 새로 '7.'에서 추가한 폴더를 지우고 백업해둔 폴더의 이름을 원래대로 바꾸어주세요. 다른 방법을 찾으셔야 합니다..) 참고 자료: phpschool - " apmsetup 에서 php 업데이트시 어떤 파일을 받아야 해요? " apmsetup - " apmsetup 7 에서 php 5.3.3 을 쓰는 문제 "

MySQL에서 BINARY 비교

PHP에서 DB에 IP를 저장해야할 일이 있었습니다. 여기 저기 찾아보니, php의 inet_pton을 이용하여 IP를 BINARY 형태로 바꾼 후 저장하는 것이 좋다고 하더군요. 그래서 BINARY 형의 열을 만들고, 다음의 질의문을 이용해 IP를 저장했습니다. "INSERT INTO log (ip, ins_date) VALUES ( ... 생략 ...)" 그리고 같은 IP를 가지는 행이 몇 개나 있는지 알아보기 위해 "SELECT count(*) FROM log WHERE ip = '... 생략 ...'"를 실행했는데, 분명히 값이 해당되는 행이 있는데도 불구하고 결과가 계속 0으로 나왔습니다. 알고 봤더니, BINARY 형은 삽입된 데이터가 자료형의 크기 보다 작은 경우, 데이터 뒤에 '\0'(null 문자)를 자동으로 추가하는데, 비교할 때는 '\0'가 있는 것과 없는 것이 다른 것으로 처리되어서 발생한 문제였습니다. 예를 들어 설명하면, log 테이블에 BINARY(16)인 ip 열이 있는데, 여기에 "abc"라는 값을 삽입하면, 실제로는 "abc\0\0\0 ..생략.. \0" 이런 값이 들어가게 되고, 만약 ip = "abc"라는 조건으로 검색을 하면, 뒤에 붙어 있는 '\0'들 때문에 제대로 검색이 되지 않습니다. 해결법은 간단합니다. BINARY 대신에 VARBINARY 형을 사용하시면 됩니다. 참고: http://www.mysqlkorea.co.kr/sub.html?mcode=manual&scode=01&m_no=21689&cat1=11&cat2=334&cat3=347&lang=k

padding 때문에 고생했습니다...

padding 때문에 고생했습니다. 분명 엘리먼트의 크기를 제대로 계산 했는데도 원하는 모양이 나오지 않더군요. 여기 저기 검색하다가 우연히 padding 값은 엘리먼트의 크기 지정과 별도라는 것을 알게 되었습니다. 지금까지 padding은 전체 크기에 포함되는 줄 알았는데, 그게 아니더군요. 엘리먼트에 크기를 지정할 때는 원하는 크기에서 padding의 크기를 빼고 지정해주어야 합니다.

PHP preg_match()에서 한글 사용 문제.

preg_match()는  PCRE(펄 호환 정규표현식)를 사용합니다. 이것을 이용해서 특정 한글 문자열을 찾으려고 했는데, 못찾더군요... 여기 저기 검색한 끝에 방법을 알았습니다. 해결법: 주어진 문자열의 인코딩이 utf-8(유니코드)로 되어 있어야 하고, 정규표현식 끝에 u 옵션을 붙여주면 됩니다.

apmsetup 환경에서 php의 curl 활성화하기.

apmsetup을 설치해서 사용하고 있는데, php에서 curl을 사용할 일이 생겼습니다. phpinfo()를 이용해서 확인해보니, curl이 활성화 되어있지 않더군요. 처음에는 설치를 해야하는 줄 알고 윈도에서 curl 설치하는 방법을 찾았는데, 알고 봤더니 그냥 설정 파일에서 주석만 해제 하면 되더군요... apmsetup이 설치된 폴더에서(기본: "C:\APM_Setup") "php.ini" 파일을 여신 후에 "extension=php_curl.dll"라는 부분을 찾으셔서(제 경우에는 611번 줄) 앞에 붙어 있는 ";"(주석 표시)를 제거하고 저장하시면 됩니다. (그 후 아파치 서버를 재시작 해주세요~)

XE 1.5에서 1.7로 업데이트를 했는데...

XE 1.5에서 1.7로 업데이트를 하게 되었습니다. 그런데... 쉬운설치로는 코어 업데이트가 않되더군요.(무슨 에러가 발생했는데, 지금은 기억나지 않습니다.) 되는 것만 하자는 생각에, 코어는 제쳐두고 최근 댓글 위젯(댓글알리미 애드온이었는지도 모르겠습니다. 기억이 잘... ^_^;)을 업데이트 하려고 했습니다. 업데이트를 하려면 코어를 1.5.2로 업데이트 해야한다고 나타나더군요. 꿩대신 닭이라고, 그럼 1.5.2라도 되라는 생각에 업데이트를 눌렀더니... 아~~! 에러 외에는 아무런 화면도 볼 수 없었습니다. 순간, 망했다라는 생각이 들었죠... 백업을 하지 않았으니까요... 그 후로 시작된 역경들... 우선 무슨 파일이 없다는 에러가 발생했습니다.   → XE 사이트에서 옛날 코어 버전(1.5.2)을 찾아서 내려받은 후 해당 파일만 직접 업로드 했습니다. 그러고 나니, 이번엔 존재하지 않는 함수를 호출했다는 에러가 나타나더군요...   → 문제의 파일을 열어서 그 함수가 어디에 포함된 것인지를 확인해봤더니, Context 클래스에 포함되어져 있더군요. 그래서 /xe/classes/context/Context.class.php를 1.5.2버전으로 바꾸었습니다. 이번에는 admin_bar.html가 없다는 에러   → "{Context::set("admin_bar", "false")}"이 내용을 텍스트 문서에 넣고  "modules/admin/tpl/"에 admin_bar.html라는 이름으로 저장했습니다. (참고: 밧떼리님의 댓글 ) 그리고 드디어 관리자 페이지를 볼 수 있었습니다. 그런데... 어째서인지 메뉴도 영어로 나오고, 화면도 전과는 완전히 다르고, 뭔가 깨진 모습이었습니다. 그래서 또 찾아보니, "웹사이트주소/index.php?module=admin" 이렇게 해야 제대로된 관리자 페이지로 이동한다고 하더군요. 여하튼 

FTP에서 확장자 없는 이미지 파일을 전송 받을 때 전송된 이미지가 깨지는 문제

사이트 관리를 하던 중에 서버를 백업하려고 Filezilla로 서버 파일들을 통째로 다 받았습니다. 그런데 이미지 파일들이 다 깨져버리더군요. 알고 봤더니 전송모드 차이 때문이었습니다.