출처 : http://vsts2010.net/411

 

VS.NET(VS2002)에서MFC 프로젝트로 만들었던 프로그램을 VC++10 프로젝트로 변환하여 컴파일 했더니 에러가 발생하면서 아래의 경고가 나왔습니다.

C:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\include\atlcore.h(35):#error This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended.

에러 내용은 프로젝트에서 정의된 _WIN32_WINNT 버전이 0x403인데atlcore.h 버전이 최소 0x0501 이상이 되어야 한다는 것입니다.

그래서 _WIN32_WINN 정의한 stdafx.h 파일을 열어보니

#define _WIN32_WINNT 0x0400

되어 있었더군요. 그래서 일단 이것을 최신이 좋다라는 생각에 아래와 같이 했습니다. ^^;;

#define _WIN32_WINNT 0x0600

그랬더니 이제는 아래와 같은 에러가 나오더군요. -_-;

c:\program files\microsoft visual studio 10.0\vc\atlmfc\include\afxcmn3.inl(29): error C2065: 'CCM_SETWINDOWTHEME' : 선언되지 않은 식별자입니다.

그래서 바로 구글링 들어갔습니다.

쉽게 저와 같은 에러가 나와서 질문을 올린 글을 찾았고 답변도 보았습니다.

문제 해결은 stdafx.h 파일에 정의된 버전의 숫자를 아래와 같이 하면 된다고 하더군요

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
#define WINVER 0x0501 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif

#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif

#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0501 // Change this to the appropriate value to target Windows Me or later.
#endif

#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
#define _WIN32_IE 0x0500 // Change this to the appropriate value to target IE 5.0 or later.
#endif

이렇게 하니 문제 없이 빌드가 성공 되었습니다.

주위에서 VC++의 새로운 버전이 나와도 쉽게 사용하지 못하는 경우가 오래 전에 만들었던 프로젝트를 포팅 할 수 없어서 이전 버전을 어쩔 수 없이 사용한다는 이야기를 종종 듣습니다.

그러나 저는 운이 좋아서인지 2002버전부터 순차적으로 새 버전의 VC++을 사용할 수 있어서 VC++6에서 VS2002로 넘어갈 때만 빌드 문제를 겪었습니다.

그래서 이런 포팅에 대한 문제는 잘 알지 못합니다. 이번에는 예전에 만들었던 코드를 C++0x 코드로 바꾸고 싶어서 오래 전에 만들었던 프로젝트를 VC++ 10로 포팅하면서 정말 정말 오랜만에 이런 문제를 겪어 보게 되고 해결 방법을 포스팅 할 수 있었습니다.

혹시 앞으로 또 이런 경우가 발생하면 바로 바로 공유하도록 하겠습니다.

 

회사에서 작업으로 받은 컴퓨터가 더 이상 작업하는데 인내심을 요구해서

(팬4 RAM 2GB ... ㅡㅡ... 아무리 장인은 연장탓을 안한다곤 하지만.. 기획자들은 i7에 ssd 보급해주면서 참...  )

현재 안쓰는 테스팅 컴퓨터가 굴러다니길래 (쿼드Q8300 RAM 5GB) 여기에

윈7 64bit 를 설치하고, 가능한 최신 컴파일러의 힘을 보고싶어서 Visual Studio도 2005 -> 2010으로 올렸습니다.

 

그런데.....

가뜩이나 빌드 환경을 적용 시키고

Lua 의 LNK2001 _lua ... 의 에러도 일일히 lib 파일을 지정 시켜서 서버 프로그램 빌드를 성공 시키는건 좋았습니다만...

 

이걸 테스트 서버 (윈2003) 에서 돌리니 프로그램이 걍 죽어 버리더군요.

 

처음엔 64비트로 컴파일 환경이 바껴서 그런가 해서 컴파일 옵션에서 전부 x86환경으로 맞췄는데 결과는 똑같아서

천상 원격 디버깅 까지 해가면서 원인을 찾아보니

 

CADODataBase::CADODataBase()
{
     ::CoInitialize(NULL);
     m_pConnection.CreateInstance(__uuidof(Connection));
     if( m_pConnection == NULL ){ 
          ASSERT(false && "CoInitialize() 를 먼저 호출해야합니다.");
          LOGCON(_T("[CADODataBase][ERROR][ADODB.Connection]\n"));  
     }
}

 

위의 ASSERT에서 죽어버리더군요.

 

그런데... 이게, 컴파일한 win7환경에선 전혀 문제없이 객체 할당에 성공시키니 뭐가 문제일까 하고 열심히 검색하던중

저랑 같은 증상으로 고생하신 분이 계시더군요.

(참고한분 블러그 입니다. http://icartsh.tistory.com/3)

 

결론은 msado15.dll 이 윈7이전이랑 이후 버젼이 있어서 만약 이후 버젼에서 컴파일 하면 위와 같은 함수에서 객체 생성에 실패할 수 도 있다는 이야기 입니다.

 

ms에선 이렇게 설명하고 있습니다.

http://support.microsoft.com/kb/2517589

 

 C:\Program Files\Common Files\System\ado

 

msado15.dll

 

실제로 저 파일의 타임 스템프가 2010년으로 찍혀 있고, 용량도 2배로 늘어있더군요.

MS가 무슨짓을 했는지 잘 모르지만, 해당 폴더의 원래 있던 msado15.dll 을 msado15_win7.dll 로 바꿔준뒤

저 파일을 다운 받아 재 컴파일 해서 테스트 해보니 이상없이 돌아가네요.

 

ㅜㅜ... 이것땜에 하루가 또... ㅠㅠ

 

Open VPN쓰려고 하다보니 서버IP (즉 회사에 있는 내 컴퓨터 IP)를 알아내야 접속이 됩니다.

 

보통  IP를 알아내는 방법은.

1. 일반적인 경우 공유기 없이 공인 IP를 사용하는 경우.

 - 도스창을 띄우고 ipconfig 를 실행해서 IP를 확인

 

 

 

2. 공유기를 사용하거나 회사내의 보안을 위해 사설IP를 사용하는 경우 다음 사이트를 이용해서 알아냅니다.

 

 http://www.tracemyip.org/ 

 

 

신입 개발자를 위한 조언
효율적으로 MSDN을 보는 방법
신영진 codewiz@gmail.com http://www.jiniya.net

윈도우 개발자를 위한 가장 기초적인, 동시에 가장 방대한 레퍼런스가 있다면 바로 MSDN일 것이다. 상당수의 고급 개발자들은 MSDN만 주어진다면 거의 모든 정보를 다 얻을 수 있다고 말하기도 한다. 하지만 아직도 초보 개발자들은 MSDN은 설치해두었지만 그 속에서 정보를 얻고 있지는 못하다. 게시판에 올린 질문에 냉소적으로 올라오는 MSDN을 참고하라는 말에 상처를 받기도 한다. 왜냐하면 정작 본인은 MSDN을 보았으나 정보를 얻지 못했기 때문이다. 이 글에서는 이러한 MSDN을 효율적으로 보는 방법에 대해서 다룰 것이다. 각 함수에 대한 정보를 보고 이해하는 방법에서부터 방대한 MSDN에서 자신이 원하는 정보를 찾기 위한 방법까지 언급할 것이다. 물론 이 과정에서 기본적인 영어 독해 실력은 필수사항이다.

MSDN에서 얻을 수 있는 가장 기초적인 정보는 개별 윈도우 API의 사용방법이다. 여러분이 OpenProcess의 정보를 얻고 싶다면 MSDN을 켜고 색인에서 OpenProcess를 입력하면 된다. 하지만 고민은 이 과정부터 시작된다. 검색된 OpenProcess가 너무 많기 때문이다. 일반적으로 PC에 설치되는 윈도우 운영체제에서 사용되는 OpenProcess 정보를 보고 싶다면 옆에 base라고 붙은 것을 클릭하면 된다.

이렇게 정보를 찾아 왔다면 MSDN은 여러분에게 OpenProcess에 대한 모든 정보를 보여줄 것이다. MSDN의 함수 설명은 총 여섯 개의 카테고리로 이루어진다. 인자 정보(Parameters), 리턴 값(Return Values), 주의 사항(Remarks), 예제 코드(Example Code), 요구 사항(Requirements), 관련 함수(See Also)가 그것이다.  

인자 정보에서 여러분이 이해해야 할 가장 큰 정보는 각 인자의 종류다. 종류는 크게 입력(in), 출력(out), 입출력(in, out)으로 나뉜다. 입력 정보의 대표적인 형태는 OpenProcess의 첫 번째 인자와 같은 것이다. OpenProcess의 첫 번째 인자는 열고자하는 프로세스 핸들의 권한을 설정하는 값으로 설명에 있는 process access rights라고 된 부분을 클릭해서 나오는 정보를 조합해서 넘기면 된다. 출력 정보의 대표적인 형태는 GetWindowText 함수에서 찾을 수 있다. GetWindowText의 두 번째 인자는 윈도우 캡션명을 저장할 문자열 포인터다. 이 공간은 출력용 포인터로 세 번째 인자인(nMaxCount)를 저장할 수 있을 만큼의 공간을 가진 버퍼를 넘겨야 한다. 끝으로 입출력 정보의 대표적인 형태는 GetVersionEx 함수에서 찾을 수 있다. GetVersionEx 함수의 유일한 인자인 lpVersionInfo는 넘기기 전에 dwOSVersionInfoSize에 구조체 크기를 지정해 주어야 한다. 이 후 함수를 호출하면 GetVersionEx 함수는 윈도우 버전 정보를 lpVersionInfo에 담아준다.

리턴 값에서 인지해야 할 가장 중요한 두 가지 정보는 성공한 경우의 리턴 값과 실패한 경우의 리턴 값이다. 또한 실패한 경우에 추가적으로 실패한 원인을 찾을 수 있는 방법에 대해서도 알아두어야 한다. 대부분의 윈도우 API의 경우 GetVersionEx 함수와 같이 성공한 경우에 0이 아닌 값을, 실패한 경우에 0을 반환한다. 또한 실패한 경우에는 추가적인 실패 원인을 GetLastError를 통해서 조회할 수 있다. 종종 GetCurrentProcess와 같이 절대 실패하지 않는 함수들도 있다. 동시에 실패하지만 MSDN에는 실패에 대한 언급이 없는 GetWindowThreadProcessId와 같은 함수도 있다. GetWindowThreadPorcessId 함수는 잘못된 윈도우 핸들이 전달되면 실패하며, 실패여부는 GetLastError를 통해서 알 수 있다.

끝으로 각 함수에 첨부되어 있는 요구 사항 표를 살펴보는 방법에 대해서 알아보자. 요구 사항 표에는 각 함수를 호출할 수 있는 운영체제가 나와 있다. 여기서는 여러분의 제품이 지원하는 운영체제의 하한선이 존재하는 가만 확인하면 된다. Windows 98을 지원해야 하는 제품이라면 VerifyVersion 함수를 정적으로 사용하는 것은 피해야 한다. 이 함수는 Windows 2000 이상부터 사용가능하기 때문이다. 굳이 이 함수를 사용해야 한다면 GetProcAddress로 동적으로 함수 주소를 구해서 사용하는 방법을 택해야 한다.

이제 한 함수의 정보를 알아내는 방법에 대해서 살펴보았다. 하지만 망망대해 같은 MSDN을 탐색하는데에는 이런 방법으로는 한계가 있다. 좀더 효과적으로 다양한 정보를 한번에 살펴볼 수 있는 방법이 필요한 것이다. 이런 방법 중에 하나가 마법과 같은 버튼인 목차 동기화(Sync Contents) 버튼에 있다. OpenProcess 설명 부분에서 이 버튼을 눌러 보자. 그러면 OpenPorcess 설명이 있는 목차로 이동하게 된다. 여기서 여러 분들은 세 가지 중요한 사항을 인지해야 한다. 하나는 OpenProcess가 있는 목차의 위치다. 두 번째는 OpenProcess와 같은 단계에있는 다른 함수들에 대한 정보다. 마지막 정보는 OpenProcess 목차 부위에 있는 기술 문서(Technical Article)이다.

설치 파일은

http://dev.mysql.com/downloads/mysql/6.0.html 

 설치법은
http://blog.naver.com/infopub/100052196232
여기 블로그를 참고..

 현재 6.0 alpha 버젼이 나와서 그걸 설치 했습니다..

 mysql 은... 무료버젼의 db 동접은 기본 100 ~ 500 정도 이지만.. (manual setting 으로 바꿀 수 있지만..) 여튼...
상용화 아닌 이상 그런 큰건 필요 없고, 어차피 sql 문법만 통하면 되는거니
상관없다고 봅니다...

(MS-SQL은 뭔가 C#이니 .asp 니... 쩝...귀찮 ㅡ_ㅡ.. )

 설치시, mysql 설치 유형에서 custom 으로 해서 include, lib 파일 모두 설치 할 수 있도록 해야 프로그래밍 하기 편합니다.

Visual Studio 셋팅은.. DirectX 하던식
Include, Lib 디렉토리 설정해 주면 됩니다...

리눅스에서 vi 를 쓸때.. make 파일 만들어서...

cc -c db.c -I/usr/include/mysql -lmysqlclient 와 같이 해줘야 하는거랑 같은 작업이죠

 기본 API 는

 /////////////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <windows.h>
#include <mysql.h>
#include <stdlib.h>

MYSQL mysql; // 자료형? 선언

void qur(char *a)
{
 if(mysql_query(&mysql, a)==0)
  printf("%15s 가 전달되었습니다\n",a);
 else
  printf("쿼리 전송 에러\n");
}


void prin()
{
 MYSQL_RES* res ;
 MYSQL_ROW row ;
 int fields;
 res = mysql_store_result( &mysql ) ;
 if(res!=0)
 {
  fields = mysql_num_fields(res) ;
  while(row = mysql_fetch_row( res ))
  {
   printf("%s \n", row[0]) ;
  }
 }
}
void main(void)
{
 
 mysql_init(&mysql) ;
 if(!mysql_real_connect(&mysql, "localhost",       // DB PC, IP
                                               "root",               // DB ID
                                               "1234",              // DB pw
                                                NULL ,  
                                                3306,                // DB Port
                                                (char *)NULL, 0))
   exit(1);
 else
  printf("연결되었습니다.\n") ;
 char qurey[1000]="show databases";
 qur(qurey);
 prin();
 qur("use rosagigantea");
 qur("show tables");
 prin();

 mysql_close(&mysql);
}

///////////////////////////////////////////////////////////////////////////////////////

위의 소스를 main.c (cpp 도 상관없고) 로 copy 해서 alt+f8 로 정렬한뒤
libmysql.lib mysqlclient.lib 를 선언해 주고 (그 winmm.lib 나.. ws2_32.lib 같은곳에)
컴파일 해보고 libmysql.dll 파일 없다고 하면...

을 다운해서

성공하면... root의 database 모든 목록이 출력됩니다.
(물론 이전에 rosagigantea 라는 db를 미리 만들어 놨습니다 ;;)

중요한건.. 역시..

mysql_real_connect(&mysql, "localhost", "root","1234", NULL,3306, (char *)NULL, 0))
이 함수 겠죠..
뜻은, mysql 쿼리를 생성한다, localhost(즉 이 컴퓨터), id는 root, 암호는 1234, 기본DB 없고, port는 3306 이란 뜻입니다.

최종적으로 성공한 화면입니다..


  보면 show databases 로 모든 db를 표시해주고

use rosagigantea (이전에 create database rosagigantea 로 db를 생성했습니다) 로 rosagigantea 라는 db를 사용하고

show tables 로 안에 있는 모든 테이블을 보여주는걸로 끝납니다.

이걸... 모듈화 해서 서버 프로그램에서 이리저리 짓거리 하는게 핵심이죠..

+ Recent posts