내가 작성한 프로그램은 아무데서나 쉽게 실행이 안된다.


다른곳에서도 실행하게 만드는 방법을 설명하겠다.


** Microsoft Visual C++ 2010 기준 **



1. Microsoft Visual C++ 2010 재배포 가능 패키지(x86) 를 설치한다. 


2. 정적 컴파일을 한다. (용량은 좀 늘어남)


솔루션 탐색기에서 프로젝트를 선택 한뒤,



'프로젝트 - 속성 - 구성 속성 - 일반'의 'MFC 사용'을 '정적 라이브러리에서 MFC사용' 로 바꾸고 컴파일을 한다.




또는

 

동적링크를 정적링크로 수정


프로젝트속성:구성속성:C/C++:코드생성:런타임라이브러리




활성 (Debug) : 다중 스레드 디버그 DLL(/MDd) => 다중 스레드 디버그 (/MTd)

활성 (Release) : 다중 스레드 DLL (/MD) => 다중 스레드(/MT)


또는


재배포 가능 패키지를 친구집에 설치해야함 (일명 서비스팩)


Posted by 캐스피

그냥 c언어 쓰다가 자바를 쓰다보니 느낀 불편한점 적음


c언어는 자바(java)에 비해 굉장히 자유롭다.


자바가 짜증나는 이유가 있다면 형변환은 엄격히 제한하면서


형변환에 사용되는 유연한 함수가 별로없고 찾기도 어렵다(있겠지만 귀찮다, c언어는 바로 raw data로 처리가 가능한데)


객체 지향 언어라 데이터 변환에 굉장히 엄격하고, 내부 실제 데이터에 접근히기도 어렵다 그리고 일일이 레퍼런스도 찾아봐야한다.


예를들어 RSA 암호화를 구현한다고 해보자.


문자열 "abcde..."라는 평문이 있으면 암호화를 하기위해 이를 "abcde.."를 아스키 코드(숫자)로 변환하고


BigInteger에 넣어야 하는데 이 BigInteger


String으로만 생성자를 받는다 BigInteger는 int로 생성자를 받으면 훨씬 편한 경우가 많은데 


String만 받는다 어의가 없다.


"abcde.." String을 "616263"같은 문자열로 변환해야하는데


이런과정이 복잡하고 귀찮다.


Posted by 캐스피
/* 
written by kaspy (kaspyx@gmail.com)
*/ 


ASCII 코드 테이블은 찾기 쉬운편인데 유니코드(Unicode) 테이블은 범위도 크고 찾기도 어려운것같다.


유니코드는 UCS-2와 UCS-4가 있는데 각각 2바이트 4바이트 크기를 가진다.


세계 모든 언어에 대한 문자를 저장하고 있고 찾아볼수있다.


바로 이 사이트이다 => http://unicode-table.com/en/


유니코드 변환을 해보자


사이트에 접속해서 검색창에 원하는 문자에대한 유니코드(Unicode) 인코딩 값을 얻을수있다.





예를들어 "닭" 이라는 문자에 대한 유니코드 인코딩 값을 찾아보겠다.



한글 "닭"에 대한 유니코드에 값은 U+B2ED이다.그냥 십육진수로 0xB2ED 라고 보면된다.


더불어서 HTML 코드 정보도 볼수 있다.


또한 각 UTF 인코딩 타입별 변환된 값을 볼수있다



"닭"이라는 한글을 UTF8로 인코딩하면 0xEB8BAD 라는 값을 가진다.


더불어서 BMP (Basic Multilingual Plane, 기본 다언어면) 정보 범위별로 값을 볼수도 있다.


(유니코드와 반드시 1:1 매칭 되진 않는다는것을 참고)




Posted by 캐스피
/* 
written by kaspy (kaspyx@gmail.com)
*/ 




 VMware란 하나의 물리적인 컴퓨터 안에 여러개의 운영체제를 설치하여 하나의 컴퓨터 안에 여러개의 컴퓨터를 사용하는 것같은 효과를 볼수 있는 프로그램이다.


활용을 극대화 하는 방법중 하나는 아래 그림처럼 VMware안에 여러대의 서버를 설치하여 운영하는 방법이다.




그것도 고정아이피로... 물론 포트 포워딩을 하면 되긴하지만... 기능이 많아질수록 여러가지 제약이 따른다.


이론적으로 하나의 이더넷 카드는 MAC주소로 통신을 하기 때문에 여러개의 아이피 할당이 가능하다. 고로 고정아이피가 여러개라면 VMware 안에 운영체제 이미지를 만들어놓고 하나의 VMware 컴퓨터 안에 여러대의 서버가 작동하는 것처럼 할수 있다.


설정하는 방법도 간단하다. VMware 안에 우분투 리눅스(Ubuntu Linux) 서버를 운영한다고 가정하고 설명하겠다.


우선 고정 아이피가 필요하다. (이건 개인적으로 알아서...)


그리고 VMware를 실행한후에 자신이 고정아이피를 설정할 가상 운영체제 이미지를 선택한후에 오른쪽 버튼을 클릭한후에 Settings를 누른다.



이후에 Hardware 탭의 Network Adapter를 클릭한후에 아래와 같이 Bridged에 설정을 해주자( 기본적으로 NAT로 되어있다.) 




그리고 VMware안에 운영체제를 직접 설정하여 고정 아이피를 설정해주면 된다.


참고로 우분투 리눅스(Ubuntu Linux) 아이피 설정은 


/etc/network/interfaces 라는 파일을 수정해주면 된다.


파일을 열어보면 기본적으로 아래와 같이 자동 아이피 방식으로 설정되어 있을 것이다.


  1. auto lo eth0
  2. iface lo inet loopback
  3. iface eth0 inet dynamic


아래와 같이 자기 아이피정보에 맞게 설정을 해준다.


  1. auto lo eth0
  2. iface lo inet loopback
  3. iface eth0 inet static
  4.         address 165.246.xx.xx
  5.         netmask 255.255.255.0
  6.         gateway 165.246.xx.1


참고로 dns 서버주소 설정은


/etc/resolv.conf 


파일에 설정하면된다. dns 주소를 잘모르겠다면 아래와 같이 입력하여 구글 네임 서버(8.8.8.8)를 등록 하도록 하자.


  1. nameserver 8.8.8.8


이후에 VM 리눅스 운영체제를 다시 시작하거나 


sudo /etc/init.d/networking restart 


명령어를 사용하면 VMware 안에서도 고정 아이피를 사용할수 있다.


VMware안에 윈도우를 사용하여 고정 아이피를 설정하고 싶다면, 


제어판 -> 네트워크 및 인터넷 -> 네트워크 및 공유 센터 -> 로컬 영역 연결로 들어가서 고정아이피를 설정하도록 하면된다.


아이피 설정후 텔넷이나 ssh, mstsc로 직접 아이피를 입력하여 접속하여 확인해보도록하자!!

Posted by 캐스피
/* 
written by kaspy (kaspyx@gmail.com)
*/ 


프로그래밍 관련 블로그를 하는것은 어려운것 같습니다.ㅡㅡ;;


특히 소스코드를 올려야하는 상황이 많은데, 이럴땐 블로깅할 소스코드를 이쁘게 꾸며주는 사이트에 올려놓고 

그것을 복사해서 사용하면 보기에도 좋고, 시간도 절약됩니다.

제가 추천하는 사이트입니다.

http://pastebin.com/

(회원가입없이 익명으로도 올릴수있습니다.)



위의 사이트에 접속해서 내가 원하는 소스코드를 올리고, 소스코드언어를 선택해서 Submit을 하면 됩니다.


빨강색 버튼왼쪽은 번호를 넣고, 오른쪽은 번호를 생략합니다.

아래는 소스코드를 복사해서 붙여넣기 했을 때 결과입니다.

* 소스코드 라인 포함

  1. #include <stdio.h>
  2.  
  3. void ex(char *pname)
  4. {
  5.         FILE *fp;
  6.         char *p;
  7.         char buf[256];
  8.         fp = fopen(pname,"r");
  9.         if ( fp == NULL )
  10.         {
  11.                 printf("passwd open error\n");
  12.         }
  13. }

* 소스코드 라인 삭제

  1. #include <stdio.h>
  2.  
  3. void ex(char *pname)
  4. {
  5.         FILE *fp;
  6.         char *p;
  7.         char buf[256];
  8.         fp = fopen(pname,"r");
  9.         if ( fp == NULL )
  10.         {
  11.                 printf("passwd open error\n");
  12.         }
  13. }


Posted by 캐스피
C Standard를 기준으로 설명하였다.

 DLL을 컴파일 할때 소스코드가 길어지고 CPP파일이 많아지고 헤더파일이 많아지면 재정의 오류가 생길수 있다. 
이상하게 헤더 중복 방직 매크로(#pragma once)를 달아놔도 컴파일을 할때 재정의 오류가 나는데 오류메시지는 보통 아래와 같다.


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

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1815): error C2375: 'listen' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(789) : 'listen' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1833): error C2375: 'ntohl' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(793) : 'ntohl' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1850): error C2375: 'ntohs' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(795) : 'ntohs' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1870): error C2375: 'recv' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(797) : 'recv' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1895): error C2375: 'recvfrom' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(803) : 'recvfrom' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1921): error C2375: 'select' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(811) : 'select' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1945): error C2375: 'send' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(818) : 'send' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1970): error C2375: 'sendto' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(824) : 'sendto' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(1996): error C2375: 'setsockopt' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(832) : 'setsockopt' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2018): error C2375: 'shutdown' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(839) : 'shutdown' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2039): error C2375: 'socket' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(843) : 'socket' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2063): error C2375: 'gethostbyaddr' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(850) : 'gethostbyaddr' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2083): error C2375: 'gethostbyname' : 재정의.링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(855) : 'gethostbyname' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2101): error C2375: 'gethostname' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(857) : 'gethostname' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2121): error C2375: 'getservbyport' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(861) : 'getservbyport' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2141): error C2375: 'getservbyname' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(865) : 'getservbyname' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2160): error C2375: 'getprotobynumber' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(869) : 'getprotobynumber' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2178): error C2375: 'getprotobyname' : 재정의.링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(871) : 'getprotobyname' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2200): error C2375: 'WSAStartup' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(875) : 'WSAStartup' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2219): error C2375: 'WSACleanup' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(879) : 'WSACleanup' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2236): error C2375: 'WSASetLastError' : 재정의.링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(881) : 'WSASetLastError' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2253): error C2375: 'WSAGetLastError' : 재정의.링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(883) : 'WSAGetLastError' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2270): error C2375: 'WSAIsBlocking' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(885) : 'WSAIsBlocking' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2287): error C2375: 'WSAUnhookBlockingHook' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(887) : 'WSAUnhookBlockingHook' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2304): error C2375: 'WSASetBlockingHook' : 재정의. 링크가 다릅니다.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock.h(889) : 'WSASetBlockingHook' 선언을 참조하십시오.

c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winsock2.h(2321): error C2375: 'WSACancelBlockingCall' :재정의. 링크가 다릅니다.

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


위의 경우는 winsock2.h 헤더파일이 2번 이상 중복되서 생긴것이다.

각각의 헤더파일이나 CPP에서 해당 헤더파일이 한번만 선언하도록 하고

나머지 #include <winsock2.h>는 주석처리하도록 하면 해결할수 있다.


Posted by 캐스피

 자신이 개발한 프로그램이 다른 컴퓨터에서도 실행하려면 배포관련 컴파일을 해야하는데 대표적으로 

Visual Stduio 2010 프로젝트 속성 -> 정적 라이브러리에서 MFC사용 옵션을 하고 컴파일 했을때 나는 오류인데 메시지는 보통 아래와 같다.

error LNK2001: __imp__wsprintfA 외부 기호를 확인할 수 없습니다.

error LNK2001: __imp__wsprintfA 외부 기호를 확인할 수 없습니다.

error LNK2019: __imp__wvsprintfA@12 외부 기호(참조 위치: "void __cdecl DbgPrintf(char *,...)" (?DbgPrintf@@YAXPADZZ) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__MessageBoxA@16 외부 기호(참조 위치: "int __cdecl JobPatch(unsigned int)" (?JobPatch@@YAHI@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__DispatchMessageA@4 외부 기호(참조 위치: _WinMain@16 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__GetMessageA@16 외부 기호(참조 위치: _WinMain@16 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__LoadAcceleratorsA@8 외부 기호(참조 위치: _WinMain@16 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__LoadStringA@16 외부 기호(참조 위치: _WinMain@16 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__RegisterClassExA@4 외부 기호(참조 위치: "unsigned short __cdecl MyRegisterClass(struct HINSTANCE__ *)" (?MyRegisterClass@@YAGPAUHINSTANCE__@@@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__LoadCursorA@8 외부 기호(참조 위치: "unsigned short __cdecl MyRegisterClass(struct HINSTANCE__ *)" (?MyRegisterClass@@YAGPAUHINSTANCE__@@@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__LoadIconA@8 외부 기호(참조 위치: "unsigned short __cdecl MyRegisterClass(struct HINSTANCE__ *)" (?MyRegisterClass@@YAGPAUHINSTANCE__@@@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__UpdateWindow@4 외부 기호(참조 위치: "int __cdecl InitInstance(struct HINSTANCE__ *,int)" (?InitInstance@@YAHPAUHINSTANCE__@@H@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__ShowWindow@8 외부 기호(참조 위치: "int __cdecl InitInstance(struct HINSTANCE__ *,int)" (?InitInstance@@YAHPAUHINSTANCE__@@H@Z) 함수)에서 확인하지 못했습니다.

error LNK2019: __imp__CreateWindowExA@48 외부 기호(참조 위치: "int __cdecl InitInstance(struct HINSTANCE__ *,int)" (?InitInstance@@YAHPAUHINSTANCE__@@H@Z) 함수)에서 확인하지 못했습니다.


이럴땐 소스코드 맨앞에 해당 함수가 익스포트된 DLL을 전처리 지시자로 선언해주면 해결할수 있다.

예를들면 아래와같다.

#pragma comment(lib,"user32")
#pragma comment(lib,"gdi32")
#pragma comment ( lib , "ws2_32.lib" )
#pragma comment(lib,"Advapi32")


Posted by 캐스피