2009/07/22

Windows 7 에서의 RAD Studio 2009 버그 해결 방법!!

얼마전 새로운 운영체제인 Windows 7 에서 C++ Builder 2009 사용시 발생하는 문제에 대하여 글을 쓴 적이 있는데 오늘 RSS Reader 를 탐독하다 해결책에 대한 글을 발견했다.







2009/04/17 - [Dev Story/Mess] - C++ Builder 2009 Bug on Windows 7



이 방법은 DLL 파일 중 조건부 점프(JZ : 0x74)를 무조건 점프(JMP : 0xEB)로 바꾸는 것이다.


1) bordbk***.dll 을 찾는다 ( Delphi 2007 의 경우 bordbk105.dll, Delphi 2009 의 경우 bordbk120n.dll 이다)

2) 원본 파일을 백업해 두고 dll 파일을 Hex Editor로 연다.

3) 다음 코드를 찾는다 (01 00 48 74 47 80 3D) 이 코드는 한번만 존재 한다.

4) 찾은 코드 중 74 를 EB 로 바꾸고 저장한다.


참고로 이 방법은 공식적인 방법이 아니란다.


자료 출처 :

http://www.delphifeeds.com/go/f/58293

http://www.delphifeeds.com/go/f/58308<

Original Post : http://neodreamer-dev.tistory.com/311

2009/07/21

헤더 중복 include 방지 #pragma once VS #ifndef ~

C++ 프로그래밍에서 헤더의 중복 #include 를 방지하는 방법으로 #pragma once 와 #ifndef 를 활용하는 방법이 있다. 이 두 방법은 모든 컴파일러에서 동작하는 것은 아니다.

우선 사용법을 보면 #pragma once 의 경우 헤더의 상단에 한번 적용 하면 된다.

#pragma once

class something
{
int a;

public:
something();
~something();

int getA( void ) { return a; };

void setA( int a1 ) { a = a1; };
}



그리고 #ifndef 를 활용하는 방법은 아래 처럼 define 이 되지 않았을 경우 지정된 값을 지정하여 이후에 다시 불러 들이는 것을 방지한다.

#ifndef __SOMETHING_H__
#define __SOMETHING_H__

class something
{
int a;

public:
something();
~something();

int getA( void ) { return a; };

void setA( int a1 ) { a = a1; };
}
#endif // __SOMETHING_H__



위 두 가지 방법은 여러가지 면에서 차이가 있다.

우선 첫 번째의 경우인 #pragma once 의 경우 컴파일러 지시자로 이를 한번 인식한 후 다음부터 같은 파일의 경우 파일을 읽기조차 하지 않는다. 그래서 컴파일 단계의 파일 해석 단계는 두 번째 방법보다 빠르다. 하지만 컴파일러 지시자로 특정 컴파일러에서만 동작을 한다. 이 지시자는 Visual C++ 5.0 이상에서만 동작을 한다.

두 번째의 경우 모든 컴파일러에서 동작을 하지만 헤더 파일을 여러번 include 를 할 경우 매번 헤더 파일을 열어서 define 여부를 확인해야 하기 때문에 컴파일 과정인 파일 해석 단계에서 첫 번째 방법보다 다소 느리다.

두 가지 방법은 속도와 호환성 문제가 얽혀 있는데 무지 큰 프로젝트가 아닐 경우 속도에서는 크게 차이가 나지 않을 것 같고 Visual C++ 에서만 작업하는 것이 아니라면 호환성을 고려하여 두번째 방법을 사용하는 것이 좋아 보인다

Original Post : http://neodreamer-dev.tistory.com/310

구조체 크기로 삽질하다

무심코 사용하는 구조체에 포함 된 함수로 메모리를 객체 수 만큼 차지 하는게 아닐까 하는 의심이 들어 테스트 해 보았다.

같은 멤버 변수를 갖는 구조체 두개를 선언하고 둘 중 하나에는 함수를 몇 개 추가하고 객체를 만들었을때 생성되는 메모리 위치를 비교해 보았다. 의심과는 다르게 메모리에 생성되는 구조체 객체는 함수에 대한 메모리 차지는 없었다.

virtual 함수의 경우 조금 다르다 하는데 그 부분은 좀 더 공부를 해 봐야겠다. (역시 기본이 중요한 것 같다.)


    struct TEST
{
int a;
int b;
int c;
int d;
int e;
int f;
};

struct TEST2
{
int a;
int b;
int c;
int d;
int e;
int f;

TEST2()
{
a = 0;
b = 1;
c = 2;
d = 3;
e = 4;
f = 5;
}

void Init()
{
a = b = c = d = e = f = 0;
}

int GetA() { return a; };
int GetB() { return b; };
int GetC() { return c; };
int GetD() { return d; };
int GetE() { return e; };
int GetF() { return f; };
};

int nSizeFunc1 = (int)sizeof(TEST); // 24
int nSizeFunc2 = (int)sizeof(TEST2); // 24

TEST *s1_1 = new TEST;
TEST *s1_2 = new TEST;

TEST2 *s2_1 = new TEST2;
TEST2 *s2_2 = new TEST2;

TEST tt1[5];
for ( int i = 0; i < 5; ++i )
{
TRACE( "%d => %p\n", i, tt1 + i );
}

// Output
0 => 0018F5E0
1 => 0018F5F8
2 => 0018F610
3 => 0018F628
4 => 0018F640

TEST2 tt2[5];
for ( int i = 0; i < 5; ++i )
{
TRACE( "%d => %p\n", i, tt2 + i );
}

// Output
0 => 0018F554
1 => 0018F56C
2 => 0018F584
3 => 0018F59C
4 => 0018F5B4


이 문제에 대한 Borland Forum 의 Lyn님의 답변
Original Post :
http://neodreamer-dev.tistory.com/309

2009/07/18

Float 형 문자열 검증하기

문자열이 Float 형 데이터가 맞는지 확인을 해야 했다.



가장 간단하고 확실한 방법은 정규식(Regular Expression)을 사용하면 될 것 같은데 문제는 MFC에서 정규식 라이브러리를 찾을 수 없다는 것이다. boost 라이브러리를 이용할 수도 있지만 현재 프로젝트에 추가 계획이 없어 검증하는 루틴을 만들어 보았다.



지수형 데이터 검증할 수 있어야 하지만 우선 단순 Float 형을 기준으로 검증 루틴을 만을어 보았다.



유효한 Float 형 문자열이 부호로 시작할 수 있으며 단 하나의 소수점만 갖고 있을 수 있다는 조건하에 구현하였다.



bool bDotFound = false;

for ( int digit = 0; digit < strData.GetLength(); ++digit )
{
TCHAR ch = strData[ digit ];

// 시작이 아닌 곳에 부호가 나타날 경우
if ( digit != 0 && ( ch == _T('+') || ch == _T('-') ) )
{
return false;
}

// 소수점에 대한 처리
if ( ch == _T('.') )
{
if ( bDotFound )
{
return false;
}

bDotFound = true;
}

// Float 형 문자열이 갖을 수 없는 문자열을 갖고 있을 경우
if (( ch < _T('0') || ch > _T('9')) && ch != _T('.') && ch != _T('+') && ch != _T('-'))
{
return false;
}
}

return true;





지수형(-123.45e-3)을 포함한 검증 루틴은 나중에 한번 만들어 보아야 겠다.<

Original Post : http://neodreamer-dev.tistory.com/308

2009/07/09

SQLite 컴파일하기 ( DLL 만들기 )

SQLite 홈페이지를 방문하면 동적 라이브러리(DLL) 파일(sqlite3.dll)을 쉽게 다운로드 받을 수 있다. 정적 라이브러리를 만들때나 직접 컴파일을 하였는데 64비트용 프로그램 개발에 필요하여 64비트 환경에서 만들어진 dll이 필요하여 컴파일 방법을 찾아 보았는데 정보가 많지 않았다.


어렵사리 찾아서 정리를 해 보았다.


준비물

   sqlite-source-3_6_16.zip

   sqlitedll-3_6_16.zip

   C++ Compiler ( Visual C++ 2005 )


우선 Visual C++ 2005에서 Win32 프로젝트 생성하고 응용프로그램 설정을 아래와 같이 종류를 DLL로 설정하고 추가 옵션에 "빈 프로젝트"로 설정한다.



생성된 프로젝트 폴더에 sqlite 소스 파일(sqlite-source-3_6_16.zip)을 풀어 놓고 sqlitedll-3_6_16.zip 파일에서 sqlite3.def 파일을 프로젝트 폴더에 풀어 놓는다.


프로젝트에 sqlite 소스 파일을 추가한다. 그리고 tclsqlite.c 와 shell.c 파일을 프로젝트에서 제거한다.


프로젝트 속성 페이지의 링크 메뉴의 입력 메뉴에서 모듈 정의 파일 항목에 sqlite3.def 로 설정한다.



위의 설정만으로 빌드를 하면 아래와 같은 링크 에러를 만나게 된다.

1>fts3_tokenizer.obj : error LNK2005: _sqlite3_api이(가) fts3.obj에 이미 정의되어 있습니다.

1>rtree.obj : error LNK2005: _sqlite3_extension_init이(가) fts3.obj에 이미 정의되어 있습니다.

1>rtree.obj : error LNK2005: _sqlite3_api이(가) fts3.obj에 이미 정의되어 있습니다.

1>sqlite3.def : error LNK2001: sqlite3_column_database_name 외부 기호를 확인할 수 없습니다.

1>sqlite3.def : error LNK2001: sqlite3_column_database_name16 외부 기호를 확인할 수 없습니다.

1>sqlite3.def : error LNK2001: sqlite3_column_origin_name 외부 기호를 확인할 수 없습니다.

1>sqlite3.def : error LNK2001: sqlite3_column_origin_name16 외부 기호를 확인할 수 없습니다.

1>sqlite3.def : error LNK2001: sqlite3_column_table_name 외부 기호를 확인할 수 없습니다.

1>sqlite3.def : error LNK2001: sqlite3_column_table_name16 외부 기호를 확인할 수 없습니다.

1>sqlite3.def : error LNK2001: sqlite3_table_column_metadata 외부 기호를 확인할 수 없습니다.

1>D:\MyProject\VS\sqlite3\Debug\sqlite3.lib : fatal error LNK1120: 7개의 확인할 수 없는 외부 참조입니다.


위의 에러들을 없애기 위해 아래 내용을 전처리기 정의에 설정한다.

   SQLITE_ENABLE_FTS3

   SQLITE_ENABLE_RTREE

   SQLITE_ENABLE_COLUMN_METADATA



마지막으로 sqlite3ext.h 내용 중 일부를 수정한다.


원본 : #define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api = 0;

수정 : #define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api;


최종 빌드한다.


위의 내용은 32비트에서 진행된 내용이다. 64비트용이라고 크게 다른건 아니고 구성 관리자에서 Win32 구성을 복사하여 x64구성을 만들고 전치리기 설정에서 WIN32를 WIN64로 바꾸면 된다.


실제 동작 여부는 아직 테스트 해

Original Post : http://neodreamer-dev.tistory.com/307