2008/11/28
강력한 무료 로컬 데이터베이스 시스템 - SQLite 3.6.6.2 Released!
얼마전 릴리즈한 3.6.6 버전을 공개한 후로 버그가 발생해서인지 곧바로 3.6.6.1 과 3.6.6.2 버전이 공개가 되었다.
이번 버전에서 수정된 사항은 다음과 같다.
- Fix a bug in the b-tree delete algorithm that seems like it might be
able to cause database corruption. The bug was first introduced in
version 3.6.6 by check-in [5899] on 2008-11-13. - Fix a memory leak that can occur following a disk I/O error.
C++ Builser 와 Visual C++ 용 라이브러리
Original Post : http://neodreamer-dev.tistory.com/205
Labels:
C++
,
C++ Builder
,
Local Database
,
SQLite
,
TistoryOldPost
,
Visual C++
,
로컬 데이터베이스
2008/11/27
작고 빠르고 편한 Open Source XML Parser - RapidXML
XML 데이터를 분석해야 할 일이 있어서 공개 소스로 이루어진 프로젝트를 찾아 보았다.
TinyXML 과 RapidXML 을 찾았는데 둘 중 가볍고 사용하기 편한 RapidXML 을 사용하기로 하였다.
RapidXML 소스를 받으면 4개의 소스 파일로만 이루어 졌다.
rapidxml.hpp
rapidxml_iterators.hpp
rapidxml_print.hpp
rapidxml_utils.hpp
rapidxml_print 는 XML을 출력하는 기능이 포함되어 있고. rapidxml_utils 은 XML 데이터 파일을 읽어들이는 기능을 한다.
기본적인 XML 데이터 탐색을 하기위해서는 rapidxml.hpp 만 포함시키면 된다.
기본적인 사용법은 아래의 소스를 보면 한눈에 알 수 있다.
RapidXML 홈페이지
TinyXML 홈페이지
Original Post : http://neodreamer-dev.tistory.com/204
TinyXML 과 RapidXML 을 찾았는데 둘 중 가볍고 사용하기 편한 RapidXML 을 사용하기로 하였다.
RapidXML 소스를 받으면 4개의 소스 파일로만 이루어 졌다.
rapidxml.hpp
rapidxml_iterators.hpp
rapidxml_print.hpp
rapidxml_utils.hpp
rapidxml_print 는 XML을 출력하는 기능이 포함되어 있고. rapidxml_utils 은 XML 데이터 파일을 읽어들이는 기능을 한다.
기본적인 XML 데이터 탐색을 하기위해서는 rapidxml.hpp 만 포함시키면 된다.
기본적인 사용법은 아래의 소스를 보면 한눈에 알 수 있다.
#include "rapidxml.hpp"
#include "rapidxml_utils.hpp"
using namespace rapidxml;
// XML 문서 데이터를 저장할 변수
vector< TCHAR > xmlData;
// XML 파일 불러오기
basic_ifstream<TCHAR> xmlFile( strFile );
xmlFile.seekg(0, ios::end);
size_t size = xmlFile.tellg();
xmlFile.seekg(0);
xmlData.clear();
xmlData.resize( size + 1);
xmlData[size] = 0;
xmlFile.read( &xmlData.front(), (streamsize)size );
// XML Parsing
xml_document< TCHAR > xmlDoc;
xmlDoc.parse<0>( &xmlData.front() );
TCHAR* Name;
TCHAR* Value;
xml_node< TCHAR >* Item;
xml_node< TCHAR >* SubItem;
xml_attribute< TCHAR >* Attr;
// root 포인터
xml_node< TCHAR >* root = xmlDoc.first_node();
// root 하위 Node 탐색
for ( Item = root->first_node(); Item; Item = root->next_sibling())
{
// Node 이름
Name = Item->name();
// Node 의 Attribute 탐색
for ( Attr = Item->first_attribute(); Attr;
Attr = Attr->next_attribute() )
{
Name = Attr->name(); // Attribute 의 이름
Value = Attr->value(); // Attribute 의 값
}
for ( SubItem = Item->first_node(); SubItem;
SubItem = SubItem->next_sibling() )
{
Name = Attr->name(); // Sub node 의 이름
}
}
RapidXML 홈페이지
TinyXML 홈페이지
Original Post : http://neodreamer-dev.tistory.com/204
2008/11/20
CodeGear RAD Studio IDE Fix Pack 2009 1.0
얼마전 출시한 CodeGear 사의 RAD Studio 2009 의 IDE 버그를 수정하는 프로그램 이다.
곧 Prism 을 포함한 정식 RAD Studio 가 출시되면 해결될 문제들이기는 하겠지만....
출처 및 다운로드 : http://andy.jgknet.de/blog/?page_id=246
Original Post : http://neodreamer-dev.tistory.com/203
Labels:
CodeGear
,
RAD Studio 2009
,
RAD Studio 2009 IDE Patch
,
TistoryOldPost
SQLite v3.6.5 Library for C++ Builder, Visual C++
C++ Builder
2008/07/25 - [Dev Story/Tips] - C++ Builder 용 SQLite Library 파일 만들기...
Visual C++
2008/07/23 - [Dev Story/Tips] - Visual C++ 2005 에서 간단하게 SQLite Database 사용하기
Original Post : http://neodreamer-dev.tistory.com/202
2008/07/25 - [Dev Story/Tips] - C++ Builder 용 SQLite Library 파일 만들기...
Visual C++
2008/07/23 - [Dev Story/Tips] - Visual C++ 2005 에서 간단하게 SQLite Database 사용하기
Original Post : http://neodreamer-dev.tistory.com/202
Labels:
C++
,
C++ Builder
,
Free Database
,
libra
,
SQLite library
,
TistoryOldPost
,
Turbo C++
,
Visual C++
강력한 무료 로컬 데이터베이스 시스템 - SQLite 3.6.6 Released!
3.6.6 버전에서 변경된 사항
- Fix a #define that prevented memsys5 from compiling
- Fix a problem in the virtual table commit mechanism that was causing
a crash in FTS3. Ticket #3497. - Add the application-defined page cache
- Added built-in support for VxWorks
SQLite official webpage
SQLite Release note
SQLite Download page
Original Post : http://neodreamer-dev.tistory.com/201
Labels:
Local Database
,
SQLite
,
TistoryOldPost
,
로컬 데이터베이스
2008/11/13
SQLite v3.6.5 Library for C++ Builder, Visual C++
C++ Builder
2008/07/25 - [Dev Story/Tips] - C++ Builder 용 SQLite Library 파일 만들기...
Visual C++
2008/07/23 - [Dev Story/Tips] - Visual C++ 2005 에서 간단하게 SQLite Database 사용하기
<
Original Post : http://neodreamer-dev.tistory.com/200
2008/07/25 - [Dev Story/Tips] - C++ Builder 용 SQLite Library 파일 만들기...
Visual C++
2008/07/23 - [Dev Story/Tips] - Visual C++ 2005 에서 간단하게 SQLite Database 사용하기
<
Original Post : http://neodreamer-dev.tistory.com/200
Labels:
SQLite
,
SQLite for C++ Builder
,
SQLite library
,
TistoryOldPost
강력한 무료 로컬 데이터베이스 시스템 - SQLite 3.6.5 Released!
3.6.5 버전에서 변경된 사항
- Add the MEMORY option to the journal_mode pragma.
- Added the sqlite3_db_mutex() interface.
- Added the SQLITE_OMIT_TRUNCATE_OPTIMIZATION compile-time option.
- Fixed the truncate optimization so that sqlite3_changes() and
sqlite3_total_changes() interfaces and the count_changes pragma
return the correct values. - Added the sqlite3_extended_errcode() interface.
- The COMMIT command now succeeds even if there are pending queries.
It returns SQLITE_BUSY if there are pending incremental BLOB I/O requests. - The error code is changed to SQLITE_BUSY (instead of SQLITE_ERROR)
when an attempt is made to ROLLBACK while one or more queries are
still pending. - Drop all support for the experimental memory allocators memsys4 and
memsys6. - Added the SQLITE_ZERO_MALLOC compile-time option.
SQLite official webpage
SQLite Release note
SQLite Download page
Original Post : http://neodreamer-dev.tistory.com/199
Labels:
DBMS
,
Local Database
,
SQLite
,
TistoryOldPost
,
로컬 데이터베이스
2008/11/11
무료 SVN Server - VisualSVN Server 1.6.2 Released
이번 버전에서 바뀐 내용
- Updated to Subversion 1.5.4. For further
. Properly handle explicit mergeinfo added in merge source (r32968, -75)
. fixed: merging of paths containing spaces (r33641, -44)
. fixed: regression in mergeinfo-aware merges against 1.5.3 (r33693, -704) - Fixed: IP address configuration for server binding can be lost on upgrade.
- Do not check for occupied TCP port on upgrade if VisualSVN Server configured to listen on specific interfaces.
2008/06/19 - [Dev Story/Tips] - VisualSVN Server 와 TortoiseSVN을 이용하기
VisualSVN Official website
VisualSVN Server page
VisualSVN Server Download P
Original Post : http://neodreamer-dev.tistory.com/198
Labels:
Subversion
,
svn
,
TistoryOldPost
,
VisualSVN Server
[BCB] 테두리없이 크기조절하기
void __fastcall TfrmMain::OnWMNcHitTest(TMessage &msg)
{
int BorderSize = 2;
TPoint MousePos;
MousePos = Point(msg.LParam & 0xFFFF, (msg.LParam >> 16) & 0xFFFF);
MousePos = ScreenToClient(MousePos);
// Check Border
if (MousePos.x <= BorderSize) msg.Result = HTLEFT;
if (Width - BorderSize <= MousePos.x) msg.Result = HTRIGHT;
if (Height - BorderSize <= MousePos.y) msg.Result = HTBOTTOM;
if (MousePos.y <= BorderSize) msg.Result = HTTOP;
if ((MousePos.x <= BorderSize) && (MousePos.y <= BorderSize))
msg.Result = HTTOPLEFT;
if ((MousePos.x <= BorderSize) && (Height - BorderSize <= MousePos.y))
msg.Result = HTBOTTOMLEFT;
if ((Width - BorderSize <= MousePos.x) && (MousePos.y <= BorderSize))
msg.Result = HTTOPRIGHT;
if ((Width - BorderSize <= MousePos.x) &&
(Height - BorderSize <= MousePos.y))
msg.Result = HTBOTTOMRIGHT;
}
Original Post : http://neodreamer-dev.tistory.com/197
Labels:
C++
,
C++ Builder
,
TistoryOldPost
,
Turbo C++
,
VCL
2008/11/10
MS CryptoAPI 를 이용한 SQLite 암호화 사용자 함수 만들기
SQLite 에는 기본적으로 지원하는 암호화 기능이 없다. 별도의 비용을 지불 해야만 암호화 기능을 사용할 수 있다.
그래서 이전에 포스팅한 자료(2008/10/30 - [Dev Story/Tips] - Microsoft CryptoAPI 를 이용한 데이터 암호화
)를 바탕으로 데이터를 암호화 하는 사용자 함수를 만들어 보았다.
그래서 이전에 포스팅한 자료(2008/10/30 - [Dev Story/Tips] - Microsoft CryptoAPI 를 이용한 데이터 암호화
)를 바탕으로 데이터를 암호화 하는 사용자 함수를 만들어 보았다.
//------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "uMain.h"
//------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//------------------------------------------------------------------------
#define ENCRYPT_ALGORITHM CALG_RC4
#define KEYLENGTH 0x00800000
static void EncryptFunc(sqlite3_context *context,
int argc, sqlite3_value **argv)
{
if (argc == 0)
sqlite3_result_error(context, "Error: No Data)", -1);
else if (argc == 1)
sqlite3_result_error(context, "Error: No Password", -1);
else if (argc != 2)
sqlite3_result_error(context, "Error: Invalid param count", -1);
else
{
const unsigned char *pwd;
pwd = (const unsigned char *)sqlite3_value_text(argv[1]);
const unsigned char *src;
src = (const unsigned char *)sqlite3_value_blob(argv[0]);
if ( strlen( pwd ) > 0 )
{
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL;
HCRYPTHASH hHash = NULL;
// Get the Handle to the default provider
if ( !CryptAcquireContext( &hCryptProv,
NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0 ) )
{
if ( GetLastError() == NTE_BAD_KEYSET )
{
if (!CryptAcquireContext(&hCryptProv,
NULL, MS_DEF_PROV,
PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
// CryptAcquireContext() failed.
sqlite3_result_error(
context,
"Error: CryptAcquireContext()",
-1);
return;
}
}
else
{
// CryptAcquireContext() failed.
sqlite3_result_error(
context,
"Error: CryptAcquireContext()",
-1);
return;
}
}
// Create Hash object
if ( !CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash ) )
{
// Error during CryptCreateHash()
sqlite3_result_error(
context,
"Error: CryptCreateHash()",
-1);
return;
}
// Hash the password
if ( !CryptHashData( hHash, pwd, strlen(pwd), 0 ) )
{
// Error during CryptHashData
sqlite3_result_error(
context,
"Error: CryptHashData()",
-1);
return;
}
// Derive a session key from the hash object
if ( !CryptDeriveKey( hCryptProv, ENCRYPT_ALGORITHM,
hHash, KEYLENGTH, &hKey ) )
{
// Error during CryptDeriveKey
sqlite3_result_error(
context,
"Error: CryptDeriveKey()",
-1);
return;
}
// Encrypt
unsigned long length = strlen(src);
unsigned char *dst = (unsigned char *)malloc(length + 1);
memcpy(dst, src, length + 1 );
if ( !CryptEncrypt( hKey, NULL, TRUE, 0, dst, &length, length ) )
{
// Error during CryptEncrypt
sqlite3_result_error(
context,
"Error: CryptEncrypt()",
-1);
free( dst );
return;
}
sqlite3_result_blob(
context,
dst,
strlen( dst ),
SQLITE_TRANSIENT );
free( dst );
}
}
}
//------------------------------------------------------------------------
static void DecryptFunc(sqlite3_context *context,
int argc, sqlite3_value **argv)
{
if (argc == 0)
sqlite3_result_error(context, "Error: No Data)", -1);
else if (argc == 1)
sqlite3_result_error(context, "Error: No Password", -1);
else if (argc != 2)
sqlite3_result_error(context, "Error: Invalid param count", -1);
else
{
const unsigned char *src;
src = (const unsigned char *)sqlite3_value_blob(argv[0]);
const unsigned char *pwd;
pwd = (const unsigned char *)sqlite3_value_text(argv[1]);
if ( strlen( pwd ) > 0 )
{
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hKey = NULL;
HCRYPTHASH hHash = NULL;
// Get the Handle to the default provider
if ( !CryptAcquireContext( &hCryptProv, NULL,
MS_ENHANCED_PROV, PROV_RSA_FULL, 0 ) )
{
if ( GetLastError() == NTE_BAD_KEYSET )
{
if (!CryptAcquireContext(&hCryptProv, NULL,
MS_DEF_PROV, PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
// CryptAcquireContext() failed.
sqlite3_result_error(
context,
"Error: CryptAcquireContext()",
-1);
return;
}
}
else
{
// CryptAcquireContext() failed.
sqlite3_result_error(
context,
"Error: CryptAcquireContext())",
-1);
return;
}
}
// Create Hash object
if ( !CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash ) )
{
// Error during CryptCreateHash()
sqlite3_result_error(
context,
"Error: CryptCreateHash()",
-1);
return;
}
// Hash the password
if ( !CryptHashData( hHash, pwd, strlen( pwd ), 0 ) )
{
// Error during CryptHashData
sqlite3_result_error(
context,
"Error: CryptHashData()",
-1);
return;
}
// Derive a session key from the hash object
if ( !CryptDeriveKey( hCryptProv, ENCRYPT_ALGORITHM,
hHash, KEYLENGTH, &hKey ) )
{
// Error during CryptDeriveKey
sqlite3_result_error(
context,
"Error: CryptDeriveKey()",
-1);
return;
}
// Decrypt
unsigned long length = strlen(src);
unsigned char *dst = (unsigned char *)malloc(length + 1);
memcpy(dst, src, length + 1 );
if ( !CryptDecrypt( hKey, NULL, TRUE, 0, dst, &length ) )
{
// Error during CryptEncrypt
sqlite3_result_error(
context,
"Error: CryptDecrypt()",
-1);
return;
}
sqlite3_result_blob(
context,
dst,
strlen( dst ),
SQLITE_TRANSIENT );
free( dst );
}
}
}
//------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
m_pDB = NULL;
}
//------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if ( m_pDB )
sqlite3_close( m_pDB );
}
//------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
int nRst = sqlite3_open( "test.db", &m_pDB );
if ( nRst != SQLITE_OK )
{
ShowMessage("Cannot open database.");
return;
}
int nResult;
nResult = sqlite3_create_function(m_pDB, "Encrypt", -1,
SQLITE_UTF8, NULL, &EncryptFunc, NULL, NULL);
nResult = sqlite3_create_function(m_pDB, "Decrypt", -1,
SQLITE_UTF8, NULL, &DecryptFunc, NULL, NULL);
sqlite3_stmt* pStmt = NULL;
const char* szChar;
String strTemp;
String strQuery;
strQuery = "SELECT Encrypt('test', '123')";
if ( sqlite3_prepare( m_pDB, strQuery.c_str(),
strQuery.Length(), &pStmt, &szChar ) == SQLITE_OK )
{
int nRow = sqlite3_data_count( pStmt );
int nCol = sqlite3_column_count( pStmt );
const char* col1name = sqlite3_column_name( pStmt, 0 );
int nRowCnt = 0;
if ( sqlite3_step( pStmt ) == SQLITE_ROW )
{
++nRowCnt;
const unsigned char* col1 = sqlite3_column_text( pStmt, 0 );
String strMsg;
strMsg.sprintf(
"ROW %d: %s => %s",
nRowCnt, col1name, col1
);
strTemp.sprintf( "%s", col1 );
ShowMessage( strMsg );
}
}
sqlite3_finalize( pStmt );
strQuery = "SELECT Decrypt('" + strTemp + "', '123')";
if ( sqlite3_prepare( m_pDB, strQuery.c_str(),
strQuery.Length(), &pStmt, &szChar ) == SQLITE_OK )
{
int nRow = sqlite3_data_count( pStmt );
int nCol = sqlite3_column_count( pStmt );
const char* col1name = sqlite3_column_name( pStmt, 0 );
int nRowCnt = 0;
if ( sqlite3_step( pStmt ) == SQLITE_ROW )
{
++nRowCnt;
const unsigned char* col1 = sqlite3_column_text( pStmt, 0 );
String strMsg;
strMsg.sprintf(
"ROW %d: %s => %s",
nRowCnt, col1name, col1
);
ShowMessage( strMsg );
}
}
sqlite3_finalize( pStmt );
}
//------------------------------------------------------------------------
Original Post : http://neodreamer-dev.tistory.com/196
Labels:
C++
,
C++ Builder
,
CryptoAPI
,
Cryptography
,
MS CryptoAPI
,
SQLite
,
SQLite Create Function
,
SQLite User Function
,
TistoryOldPost
,
Turbo C++
,
암호화
2008/11/09
C++ Builder 2006(Turbo C++) 에서 GDI+ 사용하기
우선 Include 문 보면
#define STRICT
#include <windows.h>
#include <algorithm>
using std::min;
using std::max;
#include <gdiplus.h>
이렇게 사용하도록 나와 있는데 2006 버전의 gdiplus.h 에 이미 unsing 문과 windows.h algorithm 이 이미 포함이 되었기 때문에 필요 없고 2006 버전에서는 gdiplus.h 만 포함시켜주면됩니다.
여기에 STRICT를 선언해 준 부분이 있는 STRICT를 전역으로 설정해 주어야 하는데 그러기 위해서는 프로젝트 옵션의 Conditional define 부분에 STRICT를 선언해 주어야 한다.
Original Post : http://neodreamer-dev.tistory.com/195
#define STRICT
#include <windows.h>
#include <algorithm>
using std::min;
using std::max;
#include <gdiplus.h>
이렇게 사용하도록 나와 있는데 2006 버전의 gdiplus.h 에 이미 unsing 문과 windows.h algorithm 이 이미 포함이 되었기 때문에 필요 없고 2006 버전에서는 gdiplus.h 만 포함시켜주면됩니다.
여기에 STRICT를 선언해 준 부분이 있는 STRICT를 전역으로 설정해 주어야 하는데 그러기 위해서는 프로젝트 옵션의 Conditional define 부분에 STRICT를 선언해 주어야 한다.
///////////////////////////////////////////////////////////////
//Header
// GDIPlus
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
///////////////////////////////////////////////////////////////
//Source
// Initialize GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// Shutdown GDI+
Gdiplus::GdiplusShutdown(gdiplusToken);
// Using
Gdiplus::Graphics g(Canvas->Handle);
Original Post : http://neodreamer-dev.tistory.com/195
Labels:
C++ Builder
,
GDI+
,
GDIPlus
,
TistoryOldPost
,
Turbo C++
프로그램 중복 실행 방지하기
HANDLE Mutex;
const char ProgMutex[] = "MyApp";
if (( Mutex = OpenMutex(MUTEX_ALL_ACCESS, false, ProgMutex)) == NULL )
Mutex = CreateMutex( NULL, true, ProgMutex );
else
{
MessageDlg( "Already Running", mtError, TMsgDlgButtons() << mbOK, 0 );
return 0;
}
Original Post : http://neodreamer-dev.tistory.com/194
타이틀 바를 드래그 하는 효과내기 (캡션바 없이 폼 드래깅 하기)
프로그램을 만들다 보면 타이틀 바(캡션바)가 없는 프로그램을 만들어야 하는 경우가 있는데 이때 폼의 클라이언트의 특정 부분이나 폼위의 특정 컨트롤이 캡션바 역할을 해야할 때 사용할 수 있는 방법이다.
캡션바가 눌린 것으로 인식하게끔 프로그램에 Message를 보내는 방법
클라이언트에서 버튼이 눌러진 걸 탐지하여 캡션바에서 버튼이 눌러진 것 처럼 Message 바꿔치기 하기
캡션바가 눌린 것으로 인식하게끔 프로그램에 Message를 보내는 방법
//OnMouseDown
ReleaseCapture();
Perform(WM_SYSCOMMAND, 0xF012, 0 );
//OnMouseDown
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
클라이언트에서 버튼이 눌러진 걸 탐지하여 캡션바에서 버튼이 눌러진 것 처럼 Message 바꿔치기 하기
class TForm1 : public TForm
{
...
private:
virtual void __fastcall WMNCHitTest(TWMNCHitTest &Message);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_NCHITTEST, TWMNCHitTest, WMNCHitTest)
END_MESSAGE_MAP(TForm)
};
void __fastcall TForm1::WMNCHitTest(TWMNCHitTest &Message)
{
TForm::Dispatch(&Message);
if(Message.Result == HTCLIENT)
Message.Result = HTCAPTION;
}
Original Post : http://neodreamer-dev.tistory.com/193
Labels:
C++
,
C++ Builder
,
Caption Bar Dragging
,
TistoryOldPost
,
Turbo C++
,
VCL
2008/11/01
C++ Builder 2009 Unicode 로 프로젝트 변환시 링크에러 해결 방법
C++ Builder 2009 이전 버전으로 프로젝트를 생성한 프로젝트를 2009 버전으로 바꾸어 Unicode로 전환 할 경우 아래와 같은 에러 메세지를 접할 때가 있다.
[ILINK32 Error] Error: Unresolved external 'wWinMain' referenced from C:\PROGRAM FILES\CODEGEAR\RAD STUDIO\6.0\LIB\C0W32W.OBJ
위와 같은 메세지는 프로젝트를 유니코드로 변환하지 못하는 경우에 발생하는 것으로 보인다. 2009 버전에서 새로운 프로제트를 생성하여 Unicode 로 전화하여 프로젝트 소스를 비교한 결과 차이점이 있었다.
C++ Builder 2009 이전의 프로젝트 소스
C++ Builder 2009 의 프로젝트 소스
위의 소스에서 보는 것 처럼 "tchar.h" 를 포함시키고 WinMain 함수를 바꾸어 주면 문제 없이 링크가 된다
Original Post : http://neodreamer-dev.tistory.com/192
[ILINK32 Error] Error: Unresolved external 'wWinMain' referenced from C:\PROGRAM FILES\CODEGEAR\RAD STUDIO\6.0\LIB\C0W32W.OBJ
위와 같은 메세지는 프로젝트를 유니코드로 변환하지 못하는 경우에 발생하는 것으로 보인다. 2009 버전에서 새로운 프로제트를 생성하여 Unicode 로 전화하여 프로젝트 소스를 비교한 결과 차이점이 있었다.
C++ Builder 2009 이전의 프로젝트 소스
#include <vcl.h>
#pragma hdrstop
//----------------------------------------------------------------------
USEFORM("uMain.cpp", frmMain);
//----------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
C++ Builder 2009 의 프로젝트 소스
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
//----------------------------------------------------------------------
USEFORM("uMain.cpp", frmMain);
//----------------------------------------------------------------------
WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
위의 소스에서 보는 것 처럼 "tchar.h" 를 포함시키고 WinMain 함수를 바꾸어 주면 문제 없이 링크가 된다
Original Post : http://neodreamer-dev.tistory.com/192
Labels:
C++ Builder
,
C++ Builder 2009
,
Link32 error
,
TistoryOldPost
,
Unicode Project
Subscribe to:
Posts
(
Atom
)