2010/12/30

Firebird C API - 질의문 수행 후 반영된 레코드 수 구하는 함수

struct AFFECTED_ROW
{
int Insert;
int Select;
int Update;
int Delete;

AFFECTED_ROW()
{
Init();
}

void Init()
{
Insert = 0;
Select = 0;
Update = 0;
Delete = 0;
}
};


void CTestEFBDlg::GetAffectedRow( isc_stmt_handle stmt, AFFECTED_ROW& affected )
{
static char const info_count[] = { isc_info_sql_records };
char result[64] = { 0, };
int ret = 0;

ISC_STATUS_ARRAY status;
ISC_LONG sqlcode;

affected.Init();

isc_dsql_sql_info( status, &stmt, sizeof(info_count), info_count, sizeof(result), result );

if ( status[ 0 ] == 1 && status[ 1 ] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );

char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );

CString strMsg;
strMsg.Format( _T("Fail to isc_dsql_sql_info : %d - %s"), sqlcode, CString( szMsg ) );
AppendResult( strMsg );
}
else
{
char* pCur = result;
int length;
if ( *pCur == isc_info_sql_records )
{
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;

while(*pCur != 1)
{
switch(*pCur)
{
case isc_info_req_select_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
affected.Select = isc_vax_integer(pCur, length);
pCur += length;
break;
case isc_info_req_insert_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
affected.Insert = isc_vax_integer(pCur, length);
pCur += length;
break;
case isc_info_req_update_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
affected.Update = isc_vax_integer(pCur, length);
pCur += length;
break;
case isc_info_req_delete_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
affected.Delete = isc_vax_integer(pCur, length);
pCur += length;
break;
default:
pCur++;
break;
}
}
}
}
}


GetAffectedRow( stmt, affected );

CString strMsg;
strMsg.Format( _T("%d Row(s) Updated"), affected.Update );
AfxMessageBox( strMsg );
<

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

2010/12/26

Firebird C API 질의문 수행 후 반영된 레코드 수 구하기

아래 코드는 isc_dsql_sql_info() 함수를 이용하여 질의문를 후행 한 후 반영된 레코드 수를 가져오는 코드 이다.

int del_count = 0, ins_count = 0, upd_count = 0, sel_count = 0;
static char const info_count[] = { isc_info_sql_records };
char result[64];
int ret = 0;

isc_dsql_sql_info( status, &stmt, sizeof(info_count), info_count, sizeof(result), result );

if ( status[ 0 ] == 1 && status[ 1 ] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );

char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );

CString strMsg;
strMsg.Format( _T("Fail to isc_dsql_sql_info : %d - %s"), sqlcode, CString( szMsg ) );
AfxMessageBox( strMsg );
}
else
{
char* pCur = result;
int length;
if ( *pCur == isc_info_sql_records )
{
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;

while(*pCur != 1)
{
switch(*pCur)
{
case isc_info_req_select_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
sel_count = isc_vax_integer(pCur, length);
pCur += length;
break;

case isc_info_req_insert_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
ins_count = isc_vax_integer(pCur, length);
pCur += length;
break;

case isc_info_req_update_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
upd_count = isc_vax_integer(pCur, length);
pCur += length;
break;

case isc_info_req_delete_count:
pCur++;
length = isc_vax_integer(pCur, 2);
pCur += 2;
del_count = isc_vax_integer(pCur, length);
pCur += length;
break;

default:
pCur++;
break;
}
}

CString strMsg;
strMsg.Format( _T("%d Row(s) Updated"), upd_count );
AfxMessageBox( strMsg );
}
}






isc_info_sql_records 파라메터를 이용하여 isc_dsql_sql_info() 함수를 수행 한 후의 Request Buffer 내용


Result buffer for DELETE statement contains:
23, 29,0, (isc_info_sql_records, length=29)
15, 4,0, 0,0,0,0, (isc_info_req_update_count, 0 rows updated)
16, 4,0, 4,0,0,0, (isc_info_req_delete_count, 4 rows deleted)
13, 4,0, 4,0,0,0, (isc_info_req_select_count, 4 rows selected)
14, 4,0, 0,0,0,0, (isc_info_req_insert_count)
1, (isc_info_end)

Result buffer for UPDATE statement contains:
23, 29,0,
15, 4,0, 4,0,0,0,
16, 4,0, 0,0,0,0,
13, 4,0, 4,0,0,0,
14, 4,0, 0,0,0,0,
1,

Result buffer for INSERT statement contains:
23, 29,0,
15, 4,0, 0,0,0,0,
16, 4,0, 0,0,0,0,
13, 4,0, 0,0,0,0,
14, 4,0, 1,0,0,0,
1,







isc_dsql_sql_info() 함수에 isc_info_sql_records 파라메터를 이용하여 데이터베이스에서 반영 된 레코드 수를 가져올 수 있는데 반영된 수가 누적되고 있다. 이에 대한 내용은 좀 더 분석을 해 보아야겠다. Firebird C API 의 경우 관련 자료가 많지 않아서 분석이 쉽지가 않다.





자료 출처


Firebird C API 간단 사용기

C API를 이용한 Firebird embedded 를 간단하게 사용하는 예이다. 질의문의 결과난 파라메터를 이용한 방법은 XSQLDA(eXtended SQL Descriptor Area)를 이해한 후에 정리를 해야 할 것 같다.





ClearResult();
AppendResult( _T("Try to attach database!!") );
isc_db_handle db = 0L; /* database handle */
isc_tr_handle trans = NULL; /* transaction handle */
isc_stmt_handle stmt = NULL; /* statement handle */

char szDBName[ MAX_PATH ] = "E:\TEST.FDB";
ISC_STATUS_ARRAY status;
ISC_LONG sqlcode;

// Database Parameter Block (DPB) 준비
std::string strDPB;

strDPB.append( 1, isc_dpb_version1 ); // DPB 버전
strDPB.append( 1, isc_dpb_user_name ); // User Account
strDPB.append( 1, (char)strlen("sysdba") );
strDPB.append( "sysdba" );
strDPB.append( 1, isc_dpb_password ); // Password
strDPB.append( 1, (char)strlen("masterkey") );
strDPB.append( "masterkey" );

// Database connect
if ( isc_attach_database( status, 0, szDBName, &db, (short)strDPB.length(), strDPB.c_str() ) )
{
AppendResult( _T("Fail to attach database!!") );

return;
}

// Start Transaction
isc_start_transaction( status, &trans, 1, &db, 0, NULL );

// Execute query
char szQuery[1024];

// Create Table
sprintf_s( szQuery, 1024,
"CREATE TABLE employee ("
" name VARCHAR(20) "
", birth INTEGER"
", enter TIMESTAMP"
")");

isc_dsql_execute_immediate( status, &db, &trans, strlen(szQuery), szQuery, 1, NULL );
isc_commit_transaction( status, &trans );

if ( status[0] == 1 && status[ 1 ] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );

char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );

CString strMsg;
strMsg.Format( _T("Fail to Create Table : %d - %s"), sqlcode, CString( szMsg ) );
AppendResult( strMsg );
}
else
{
AppendResult( _T("Table Creaded.") );
}

// Insert Data
isc_start_transaction( status, &trans, 1, &db, 0, NULL );
AppendResult( _T("Insertion!!") );
for ( int i = 0; i < 5; ++i )
{
sprintf_s( szQuery, 1024,
"INSERT INTO employee ( name, birth, enter ) VALUES ( 'name%d', %d, CURRENT_TIMESTAMP )"
, i, 20 + i
);

isc_dsql_execute_immediate( status, &db, &trans, strlen(szQuery), szQuery, 1, NULL );

if ( status[0] == 1 && status[ 1 ] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );

char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );

CString strMsg;
strMsg.Format( _T("Fail to Insert : %d - %s"), sqlcode, CString( szMsg ) );
AppendResult( strMsg );
}
else
{
AppendResult( _T("1 Row Inserted.") );
}
}

// Update Data
// Statement allocation
isc_dsql_allocate_statement( status, &db, &stmt );

AppendResult( _T("Update!!") );
sprintf_s( szQuery, 1024, "UPDATE employee SET birth = birth + 2 WHERE birth > 22");

isc_dsql_prepare( status, &trans, &stmt, 0, szQuery, 0, NULL );

isc_dsql_execute( status, &trans, &stmt, 0, NULL );
isc_commit_transaction( status, &trans );

if ( status[ 0 ] == 1 && status[ 1 ] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );

char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );

CString strMsg;
strMsg.Format( _T("Fail to Update : %d - %s"), sqlcode, CString( szMsg ) );
AppendResult( strMsg );
}
else
{
AppendResult( _T("Table Updated") );
}

isc_dsql_free_statement( status, &stmt, DSQL_close );

// Delete Table
AppendResult( _T("Drop Table!!") );
sprintf_s( szQuery, 1024, "DROP TABLE employee");

isc_dsql_execute_immediate( status, &db, &trans, strlen(szQuery), szQuery, 1, NULL );

// Commit Transaction
isc_commit_transaction( status, &trans );

// Database disconnect
isc_detach_database( status, &db );

AppendResult( _T("Database detached!!") );
AppendResult( _T("Finished!!") );
<

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

2010/12/09

SQLite Release 3.7.4.0 (정적/동적 라이브러리 포함)

SQLite 가 버전업이 되었다. 3.7.2 버전 미만을 사용하고 있을경우 업그레이드를 권장하고 있다.




SQLite Release 3.7.4 On 2010 December 08 (3.7.4)


  • Added the sqlite3_blob_reopen() interface to allow an existing sqlite3_blob object to be rebound to a new row.

  • Use the new sqlite3_blob_reopen() interface to improve the performance of FTS.

  • VFSes that do not support shared memory are allowed to access WAL databases if PRAGMA locking_mode is set to EXCLUSIVE.

  • Enhancements to EXPLAIN QUERY PLAN.

  • Added the sqlite3_stmt_readonly() interface.

  • Added PRAGMA checkpoint_fullfsync.

  • Added the SQLITE_FCNTL_FILE_POINTER option to sqlite3_file_control().

  • Added support for FTS4 and enhancements to the FTS matchinfo() function.

  • Added the test_superlock.c module which provides example code for obtaining an exclusive lock to a rollback or WAL database.

  • Added the test_multiplex.c module which provides an example VFS that provides multiplexing (sharding) of a DB, splitting it over multiple files of fixed size.

  • A very obscure bug associated with the or optimization was fixed.





이번 버전 역시 정적 라이브러리 컴파일 시도 할 때 sqlite3rtree.h 파일이 없어 sqlite-src-3070400.zip\sqlite-src-3070400\ext\rtree\ 에 포함되어 있던 파일을 이용하였다.




SQLite Homepage




2010/12/08

Windows Server 2008 의 암호 복잡성 만족 기능 해제 하기

R2 버전부터 기본으로 적용되어 있는 것으로 보이는데 Server 2008 에서는 계정에 대한 암호를 설정할 때 정해진 복잡성을 만족해야만 되도록 설정되어 있다.



이 기능은 로컬 그룹 정책 편집기에서 해제할 수 있다.




로컬 그룹 정책 편집기(gpedit.msc) 를 실행하고 "로컬 컴퓨터 정책 -> 컴퓨터 구성 -> Windows 설정 -> 보안설정 -> 계정 정책 -> 보안 정책" 의 "암호는 복잡성을 만족해야 함" 항목을 "사용 안 함"으로 설정 하면 된다.



2010/12/01

Virtual Box 의 Ubuntu 해상도 설정하기

Virtual Box 에 설치한 Ubuntu 의 해상도를 windows 처럼 창크기 변경에 따른 해상도 변경하기.



Ubuntu 9.x

게스트 확장 설치후 /etc/X11/xorg.conf 파일의 Device 섹션에 Driver “vboxvideo” 추가


Section "Device"

Identifier "Configured Video Device"

Driver "vboxvideo"

EndSection




Ubuntu 10.x

sudo apt-get install virtualbox-ose-guest-x11<

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

2010/11/01

Firebird C API 로 Firebird Embedded 사용하기

Firebird Embedded 패키기에서 아래 파일을 프로젝트 폴더에 복사를 한다.



  • fbembed.dll

  • firebird.conf

  • firebird.msg

  • ib_util.dll

  • icudt30.dll

  • icuin30.dll

  • icuuc30.dll


fbembed.dll 을 fbclient.dll 로 이름을 바꾸고 일반적인 Firebird 를 사용하듯 하면 된다.






아래 코드는 테스트를 위한 코드이다.




isc_db_handle        db = NULL;        /* database handle */
isc_tr_handle trans = NULL; /* transaction handle */
ISC_STATUS_ARRAY status; /* status vector */
long sqlcode; /* SQLCODE */

char *szDBName = "e:\ est.fdb";

// 데이터베이스 생성 DDL
std::string strQuery = "CREATE DATABASE 'e:\ est.fdb' USER 'sysdba' PASSWORD 'masterkey';";

// 데이터베이스 생성 시도
isc_dsql_execute_immediate(status, &db, &trans, 0, strQuery.c_str(), 1, NULL);

if ( status[0] == 1 && status[1] > 0 )
{
sqlcode = isc_sqlcode(status);

char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
char szMsg2[512];
ISC_STATUS* pStatus = status;
isc_interprete( szMsg2, &pStatus );
TRACE( "Fail to create database : %d - %s (%s)\n", sqlcode, szMsg, szMsg2 );

if ( sqlcode == -902 )
{
TRACE( "Database exists!!\n" );
}
else
{
return;
}
}
else
{
TRACE( "Database created!!!\n" );
}

isc_detach_database( status, &db );

char *dpb_buffer = 0; // Database Parameter Buffer
short dpb_length = 0;

// Set parameter User Name and Password
/*
isc_expand_dpb( &dpb_buffer, &dpb_length
, isc_dpb_num_buffers, 80
, isc_dpb_user_name, "sysdba"
, isc_dpb_password, "masterkey"
, isc_dpb_connect_timeout, 180
);
//*/

// Database Parameter Block (DPB) 준비
std::string strDPB;

strDPB.append( 1, isc_dpb_version1 ); // DPB 버전
strDPB.append( 1, isc_dpb_user_name ); // User Account
strDPB.append( 1, (char)strlen("sysdba") );
strDPB.append( "sysdba" );
strDPB.append( 1, isc_dpb_password ); // Password
strDPB.append( 1, (char)strlen("masterkey") );
strDPB.append( "masterkey" );
strDPB.append( 1, isc_dpb_num_buffers );
strDPB.append( 1, (char)1 );
strDPB.append( 1, (char)90 );
strDPB.append( 1, isc_dpb_connect_timeout );
strDPB.append( 1, (char)4 );
strDPB.append( 1, (char)180 );
strDPB.append( 1, (char)(180 >> 8) );
strDPB.append( 1, (char)(180 >> 16) );
strDPB.append( 1, (char)(180 >> 24) );

int nParam = (int)strDPB.length();

// 데이터베이스 연결
//isc_attach_database( status, (int)strlen( szDBName ), szDBName, &db, dpb_length, dpb_buffer );
isc_attach_database( status, (int)strlen( szDBName ), szDBName, &db,
(short)strDPB.length(), strDPB.c_str() );

if ( status[0] == 1 && status[1] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode( status );

char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
TRACE( "Fail to connect Database : %d - %s\n", sqlcode, szMsg );
return;
}
else
{
TRACE( "Database connected!!\n" );
}

isc_start_transaction( status, &trans, 1, &db, 0, NULL );

// 테이블 생성
isc_dsql_execute_immediate( status, &db, &trans, 0,
"CREATE TABLE member ( name VARCHAR(20), age INTEGER )", 1, NULL );

if ( status[0] == 1 && status[1] > 0 )
{
// Error occurred
sqlcode = isc_sqlcode(status);

char szMsg[512];
isc_sql_interprete( (short)sqlcode, szMsg, 512 );
TRACE( "Fail to Create table : %d - %s\n", sqlcode, szMsg );

isc_rollback_transaction( status, &trans );

// Release parameter buffer
isc_free( dpb_buffer );

isc_detach_database( status, &db );

return;
}
else
{
TRACE( "Table created!!\n" );
}

isc_commit_transaction( status, &trans );

// Release parameter buffer
isc_free( dpb_buffer );

isc_detach_database( status, &db );
<

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

2010/10/28

SQLite Release 3.7.3.0 (정적/동적 라이브러리 포함)





SQLite Release 3.7.3 On 2010 October 08 (3.7.3)

  • Added the sqlite3_create_function_v2() interface that includes a destructor callback.

  • Added support for custom r-tree queries using application-supplied callback routines to define the boundary of the query region.

  • The default page cache strives more diligently to avoid using memory beyond what is allocated to it by SQLITE_CONFIG_PAGECACHE. Or if using page cache is allocating from the heap, it strives to avoid going over the sqlite3_soft_heap_limit64(), even if SQLITE_ENABLE_MEMORY_MANAGEMENT is not set.

  • Added the sqlite3_soft_heap_limit64() interface as a replacement for sqlite3_soft_heap_limit().

  • The ANALYZE command now gathers statistics on tables even if they have no indices.

  • Tweaks to the query planner to help it do a better job of finding the most efficient query plan for each query.

  • Enhanced the internal text-to-numeric conversion routines so that they work with UTF8 or UTF16, thereby avoiding some UTF16-to-UTF8 text conversions.

  • Fix a problem that was causing excess memory usage with large WAL transactions in win32 systems.

  • The interface between the VDBE and B-Tree layer is enhanced such that the VDBE provides hints to the B-Tree layer letting the B-Tree layer know when it is safe to use hashing instead of B-Trees for transient tables.

  • Miscellaneous documentation enhancements.




이번 버전에서는 정적 라이브러리를 만들기 위해 컴파일을 시도 하면 sqlite3rtree.h 파일을 찾을 수 없다는 에러 메세지가 발생하였다. 이 문제에 대한 자료를 찾기가 어려워 우선 sqlite3rtree.h 파일을 sqlite-3.7.3.tar.gz 파일에서 찾아(sqlite-3.7.3.tar.gz\sqlite-3.7.3.tar\sqlite-3.7.3\ext\rtree\) 넣어 컴파일을 하였다





2010/10/21

AnkhSVN에서 .DLL 과 .LIB 파일을 SVN 에 등록하기


2010/10/16 - [Dev Story] - AnkhSVN 으로 Subversion에서 프로젝트 받아오기




AnkhSVN 으로 프로젝트를 SVN 에 올릴 경우 프로젝트에 포함된 .DLL 파일과 .LIB 파일이 SVN Repository 에 등록이 되지 않는데 이를 등록하는 방법을 지금까지 찾을 수 없었는데 의외로 간단한 방법을 찾았다.




AnkhSVN 에 포함되어 있는 Working Copy Explorer 을 이용하면 해결 할 수 있다. Working Copy Explorer 는 PC에서 작업중인 프로젝트를 탐색할 수 있으면 SVN 관련 작업을 지원하는 View 이다. Visual Studio 의 View 메뉴에서 Working Copy Explorer 를 호출 할 수 있다.







Repository에 등록되지 않은 파일들을 등록하길 원할 경우 해당 파일에서 오른쪽 버튼의 Subversion 메뉴에서 할 수 있다.<

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

2010/10/18

CFileDialog 여러개의 파일 선택하기

CFileDialog dlgFile( TRUE, NULL, NULL, 
OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT,
_T("All files (*.)|*.*") );

int nFileNum = 100;
int nFileNameSize = MAX_PATH + 1;
int nBufSize = nFileNameSize * nFileNum + 1;
TCHAR* szFileNames = new TCHAR[ nBufSize ];

szFileNames[ 0 ] = NULL;
szFileNames[ nBufSize - 1 ] = NULL;

dlgFile.m_ofn.lpstrFile = szFileNames;
dlgFile.m_ofn.nMaxFile = nBufSize;

if ( dlgFile.DoModal() == IDOK )
{
POSITION pos = dlgFile.GetStartPosition();

while ( pos != NULL )
{
CString strFile = dlgFile.GetNextPathName( pos );
}
}

delete [] szFileNames;
<

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

2010/10/17

OpenCV 2.1 + TBB 를 Visual Studio 2010 에서 컴파일하기

OpenCV 가 2.1 버전에서 OpenMP 를 버리고 Threading Building Blocks(이하 TBB)를 선택하였는데 성능면에서 어떠한 이득이 있을지는 모르겠다. 실제로 테스트를 해 보기 위해서 OpenCV 2.1 버전을 TBB 를 활성화하여 컴파일을 해보려 했지만 쉽지 않았다.



인터넷에서 해당 정보를 찾아 보았지만 TBB 를 포함한 컴파일에 대한 설명은 많지도 않고 자세하지도 않았다. 그러던 중 한 사이트(http://blog.csdn.net/effenberg11/archive/2010/07/05/5712724.aspx)를 발견하고 그 실마리를 얻었다.




준비사항




우선 CMake 를 설치한다. 설치하지 않고도 가능하겠지만 많은걸 입력해 주어야 한다.

그리고 TBB 와 OpenCV 를 작업 경로에 압축을 풀어 놓는다. 아래는 이번 작업에 사용 된 폴더 구조이다.




OpenCV 경로 : D:\Work\OpenCV\x86

TBB 경로 : D:\Work\OpenCV\tbb30_20100406oss




설치된 CMake  GUI 버전을 실행시킨다. 그리고 소스 코드 경로(Where is the source code)에 OpenCV 의 경로 D:\Work\OpenCV\x86 를 입력하고 바이너리 생성 경로(Where to build the binaries)에 OpenCV 의 경로 D:\Work\OpenCV\x86 를 입력하고 하단의 "Configure" 버튼을 클릭한다.




"Configure" 버튼을 누르면 컴파일러를 선택하는 대화상자가 나오는데 이 대화상자에서 "Visual Studio 10" 과 "Use default native compilers" 를 선택한다.




컴파일러 선택 후 "Configure" 버튼을 클릭하면 온통 붉은색으로 뒤덥힌 리스트를 만나게 된다. 그리고 WITH_TBB 가 체크되지 않음을 확인할 수 있다.




TBB 를 활성화 하기 위해 WITH_TBB 항목을 선택하고 "Configure" 버튼을 누른다.




그러면 TBB에 대한 잘 못 된 항목(TBB_INCLUDE_DIR) 값이 리스트 상단에 표시가 된다.




TBB_INCLUDE_DIR 항목에 TBB 경로의 Include 경로를 지정하고 "Configure" 버튼을 누른다.




다음 에러는 TBB_LIB_DIR 경로 오류가 발생한다.




TBB_LIB_DIR 에 TBB 의 lib 폴더에서 플랫폼과 컴파일러 버전을 맞추어 경로를 선택한다.





경로 설정을 마치고 "Configure" 버튼을 누르면 모든 에러가 해제되고 새롭게 등록된 두 항목을 확인할 수 있다.




그리고  Use TBB 가 활성화 된 것을 확인할 수 있다.




이제 OpenCV를 압축해제 해 놓은 경로(D:\Work\OpenCV\x86)에서 OpenCV.sln 파일을 Visual Studio 2010 으로 열어 ALL_BUILD 프로젝트의 속성 대화상자를 연다.




속성 대화상자에서 VC++ Directories 항목중에서 Executable, Include, Library Directories 에 TBB 관련 경로를 입력한다.




프로젝트의 속성을 편집하는 것은 이 글의 가장 위에서 언급한 사이트로 부터 얻은 정보인데 이 속성을 편집하지 않아도 OpenCV는 에러없이 컴파일 된다. (TBB가 정상동작 할지는 확실하지 않지만...)




이제 ALL_BUILD 만 Build 하면 된다.

Build 를 마치면 Binary 생성 경로에 bin 과 lib 폴더 안에 관련 dll 과 lib 파일이 생성된다.




이제 실제로 되는지 테스트하는 일만 남았다.<

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

2010/10/16

AnkhSVN 으로 Subversion에서 프로젝트 받아오기

2010/10/16 - [Dev Story/Tips] - Visual Studio 를 위한 버전 관리 툴 AnkhSVN 사용하기



AnkhSVN 을 이용하여 Subversion 에 등록한 프로젝트를 다른 곳에서 다운 받아 보았다.




우선 File 메뉴에서 Subversion 의 "Open from Subversion..." 을 선택한다.




Subversion URL 을 입력하면 프로젝트 폴더가 나오고 프로젝트 폴더에 들어가면 Solution(*.sln) 파일이 있는데 이를 Open 한다.




프로젝트를 생성할 경로를 입력하고 "OK" 를 누른다.




그러면 Subversion 서버로 부터 프로젝트를 다운 받는다.




다운받은 프로젝트가 이상이 없는지 컴파일을 해 보았다.

그런데 문제가 발생하였다. 프로젝트에 포함되어 있던 *.lib 와 *.dll 파일들이 Subversion 서버에 등록이 되지 않아있었다.




프로젝트를 등록할 때 .lib 와 .dll 파일들이 자동으로 등록이 되지 않는 것 같다. 별도의 옵션이 있는지 확인해 보고 없으면 프로젝트 등록은 TortoiseSVN 같은 별도의 툴을 사용해야 할 것 같다.<

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

Visual Studio 를 위한 버전 관리 툴 AnkhSVN 사용하기

먼저 AnkhSVN 홈페이지에서 설치 파일을 다운로드 받는다. AnkhSVN 은 여러가지 버전이 있는데 최근 안정화 된 AnkhSVN 2.1.8420 버전을 설치 하였다.



AnkhSVN 을 설치하면 Visual Studio 의 Tools -> Options 의 Source Control 항목에 AnkhSVN 이 표시가 되고 Subversion 에 관련한 설정을 할 수 있다.




새로운 프로젝트 생성 대화상자에도 Add Subversion 메뉴가 생성이 되어 프로젝트를 생성할 때 바로 Subversion 에 등록을 할 수 있다.




기존 프로젝트를 Subversion 에 등록을 하려면 Solution Explorer 에서 해당 프로젝트에서 마우스 오른쪽 버튼을 누르면 Subversion 관련 메뉴가 나오는데 이 중에서 Add Solution to Subversion 을 실행하면 된다.




새로운 프로젝트를 Subversion 에 등록하는 것과 기존 프로젝트를 Subversion에 등록하는 것으 크게 차이가 없다. 여기에서는 기존 프로젝트를 Subversion 에 등록을 해 보겠다.




기존 프로젝트른 Embedded Firebird 를 테스트해 보기위한 간단한 프로젝트이고 Subversion 은 Google에서 제공하는 Google code project hosting 을 이용하였다.




Add Solution to Subversion 에서 프로젝트 이름과 Subversion URL 만 넣어주면 된다.





프로젝테에 대한 적당한 로그를 작성한다.




Google code 에 접속 정보를 입력하면 프로젝트가 Subversion 에 등록이 된다.



이세 Solution Explorer 에서 소스파일 아이콘 좌측에 등록이 되었다는 (+)아이콘이 표시되는 걸 볼 수 있다. Commit 을 해야 완전하게 등록이 되는 것으로 프로젝트의 마우스 우측 메뉴에서 Commit Project Changes 를 선택한다.




Commit 대화상자에는 변경된 파일 리스트와 Log Message 입련하는 곳이 있는데 적당한 메세지를 입력하고 OK 를 선택하여 Commit 한다.







Commit 을 마치면 Solution Explorer 의 파일 아이콘들이 바뀐 것을 볼 수 있다.


2010/10/08

Visual C++ 에서 64비트 정수 출력하기

__int64    i64 = 0x12341234abcdabcd;

char szDispBuf[1024];

sprintf_s( szDispBuf, 1024,
"%%d => %d \n"
"%%o => 0%o \n"
"%%x => 0x%x \n"
"%%X => 0x%X \n"
"%%I64d => %I64d \n"
"%%I64o => 0%I64o \n"
"%%I64x => 0x%I64x \n"
"%%I64X => 0x%I64X \n"
, i64, i64, i64, i64, i64, i64 );

TRACE("%s \n", szDispBuf );

Output:
%d => -1412584499
%o => 02215011064
%x => 0xabcdabcd
%X => 0x12341234
%I64d => 1311693408901639117
%I64o => 0110640443225363325715
%I64x => 0x12341234abcdabcd
%I64X => 0x12341234ABCDABCD
<

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

2010/10/05

Firebird Windows에 수동으로 설치하기

우선 운영체제에 맞는 설치 파일을 선택한다. 32비트는 Firebird-2.5.0.26074-0_Win32.zip 를 64비트는 Firebird-2.5.0.26074-0_x64.zip 를 설치하고자 하는 경로에 압축을 풀어놓는다. (Download Site)






여기서는 F:\Firebird64 경로에 압축을 풀고 작업을 했다.






우선 bin 폴더에 있는 install_super.bat 를 실행하여 서비스를 등록한다.






이제 시스템의 서비스 목록을 확인해 보면 Firebird Guardian 과 Firebird Server 가 등록되어 있음을 확인 할 수 있다.






사실 이것 만으로 설치는 끝난것인데 항상 Firebird 를 운영할 일이 없는 개인 PC 에서 서비스 형태로 돌리는 것이 맘이 들지 않아 Application 형태로 필요할 때에 운영을 하려 한다.






우선 F:\Firebird64\system32 폴더에 있는 Firebird2Control.cpl 를 윈도우의 System 폴더(C:\Windows\System32)에 복사를 한다. 복사를 하고 시작 메뉴의 제어판을 보면 Firebird Server Manager 가 등록 된다.






Firebird Server Manager를 실행하면 Firebird Server Control 이 실행 된다.






Firebird Server Control 에서 현재 운영중이라면 서버를 중지시키고 운영 형태(Run)를 Application 으로  시작(Start)를 Manually로 설정하고 Apply 를 누르고 시작을 한다.






그러면 시스템의 서비스 목록에 등록되었던 두 개의 서비스(Firebird Guardian, Firebird Server)가 사라지고 Firebird 는 Application 형태로 운영이 된다. 시스템의 프로세스 목록을 보면 두개의 프로세스가 동작중인 것을 확인 할 수 있다.





<

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

2010/10/04

Firebird 2.5 정식 Release!!







Firebird 2.5가 기나긴 RC 버전 뒤로하고 정식 버전을 공개하였다.




Scrollbar 유무 확인하기

Scrollbar 의 유무를 확인하는 것은 윈도우의 스타일을 확인하면 할 수 있다.




DWORD dwStyle = GetWindowLong( hWnd, GWL_STYLE )

if ( dwStyle & WS_HSCROLL )
{
//Horizontal scrollbar is visible
}

if ( dwStyle & WS_VSCROLL )
{
//Vertical scrollbar is visible
}
<

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

2010/09/29

C++ 키보드 상태 알아내기2




bool bLCtrl = (GetKeyState(VK_LCONTROL) & 0x8000) != 0;
bool bLShift = (GetKeyState(VK_LSHIFT) & 0x8000) != 0;
bool bLMenu = (GetKeyState(VK_LMENU) & 0x8000) != 0;

bool bCapsLock = GetKeyState( VK_CAPITAL ) != 0;
bool bNumLock = GetKeyState( VK_NUMLOCK ) != 0;
bool bScrollLock = GetKeyState( VK_SCROLL ) != 0;

TRACE("Caps Lock : %s, Num Lock : %s, Scroll Lock : %s \n"
, ( bCapsLock )? "ON": "OFF"
, ( bNumLock )? "ON": "OFF"
, ( bScrollLock )? "ON": "OFF"
);
<

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

2010/09/18

[Android Tips] 화면 상태 확인 하기

현재 화면이 가로인지 새로인지 확인하는 방법은 화면 해상도를 확인하는 방법도 있겠지만 API 에서 제공하는 함수로도 확인 할 수 있다. 가로 혹은 세로 해상도가 같은 경우에는 API 함수를 이용하는 것이 보다 정확할 것이다.





Android 2.1 이하에서는 getOrientation() 만 동작하며 Android 2.2 이상에서는 getOrientation() 과 getRotation() 이 동작을 한다.






Android 2.1 이하


WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
Display disp = wm.getDefaultDisplay();

int orientation = disp.getOrientation(); // Android 2.1
Log.i( "Orientation", "orientation : " + orientation );






Android 2.2 이상


WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
Display disp = wm.getDefaultDisplay();

int rotation = disp.getRotation(); // Android 2.2
Log.i( "Rotation", "rotation : " + rotation );

switch ( rotation )
{
case Surface.ROTATION_0:
Log.i( "Roation", "Portrait : 0" );
break;

case Surface.ROTATION_90:
Log.i( "Roation", "Landscape : 90" );
break;

case Surface.ROTATION_180:
Log.i( "Roation", "Portrait : 180" );
break;

case Surface.ROTATION_270:
Log.i( "Roation", "Landscape : 270" );
break;
}
<

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

[Android Tips] 화면 해상도 알아내기


방법 #1


DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int ScreenWidth = metrics.widthPixels
int ScreenHeight = metrics.heightPixels






방법 #2


WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
Display dsp = wm.getDefaultDisplay();

int height = dsp.getHeight();
int width = dsp.getWidth();
<

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

2010/09/15

[Android Dev.] 화면 회전에 대응하는 UI 구성하기

안드로이드 기기를 보통 사용하는 세로(portrait) 방향 화면에서 가로(landscape) 방향 화면으로 전환하는 것에 대응 하기 위해 서는 서로 다른 Layout 을 구성하는 리소스(xml)를 만들어야 한다.





아주 단순한 layout 구성으로 기본적인 TextView 와 버튼 두개로 구성된 UI 이다. 파일 이름은 main.xml 이다.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical|center_horizontal"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
/>
</LinearLayout>






위의 layout 구성은 아래와 같은 화면이다.






이 화면을 가로(Landscape)로 변경(에뮬레이터에서 Ctrl+F11)을 하면 아래와 같은 화면이 된다. UI 구성이 변하지 않은 화면이 나온다.






세로 방향 구성과는 다르게 가로 방향의 UI 구성을 새로 하기 위해서는 res 폴더에 layout-land 폴더를 만들고 layout 폴더에 있는 구성 파일과 동일한 UI 구성 파일(xml)을 만들어 작성을 하면 화면의 회전에 따라 각각의 UI 구성이 출력 된다.






아래는 layout-land 폴더에 작성한 main.xml 파일 이다.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical|center_horizontal"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical|center_horizontal"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
/>
</LinearLayout>
</LinearLayout>






이 소스를 실행 시켜서 화면 전환을 해 보면 아래와 같은 변화된 UI 의 화면을 볼 수 있다.

2010/08/30

SQLite Release 3.7.2.0 (정적/동적 라이브러리 포함)




SQLite 가 3.7.2 버전을 공개하였고 이하의 버전을 사용하는 경우 업그레이드를 권고하고 있다.



2010 August 24 (3.7.2)


  • Fix an old and very obscure bug that can lead to corruption of the database free-page list when incremental_vacuum is used.





2010 August 23 (3.7.1)


  • Added new commands SQLITE_DBSTATUS_SCHEMA_USED and SQLITE_DBSTATUS_STMT_USED to the sqlite3_db_status() interface, in order to report out the amount of memory used to hold the schema and prepared statements of a connection.

  • Increase the maximum size of a database pages from 32KiB to 64KiB.

  • Use the LIKE optimization even if the right-hand side string contains no wildcards.

  • Added the SQLITE_FCNTL_CHUNK_SIZE verb to the sqlite3_file_control() interface for both unix and windows, to cause database files to grow in large chunks in order to reduce disk fragmentation.

  • Fixed a bug in the query planner that caused performance regresssions relative to 3.6.23.1 on some complex joins.

  • Fixed a typo in the OS/2 backend.

  • Refactored the pager module.

  • The SQLITE_MAX_PAGE_SIZE compile-time option is now silently ignored. The maximum page size is hard-coded at 65536 bytes.






<

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

2010/08/05

SQLite Release 3.7.0.1 (정적/동적 라이브러리 포함)

이번 버전에서 바뀐 사항

  • Fix a potential database corruption problem that can result if the same database file is alternately written by version 3.7.0 and 3.6.23.1. See ticket [51ae9cad31] for details.

  • Fix a possible performance regression caused by the introduction of automatic indexing.





2010/07/23

CMenu 의 메뉴가 존재 하는지 확인하기

MFC 의 CMenu 객체 중에서 특정 메뉴가 존재 하는지 확인 하기 위해서는 CMenu::CheckMenuItem 함수를 사용하면 된다.





이 함수는 아래와 같은 형태를 갖추고 있으며 반환값으로 메뉴의 체크 여부 또는 메뉴가 존재 하지 않을 경우 0xFFFFFFFF 를 반환한다.



UINT CheckMenuItem(
UINT nIDCheckItem,
UINT nCheck
);







아래는 사용 예이다.



bool bExist = ( m_Menu.CheckMenuItem( IDM_MYMENU, MF_BYCOMMAND ) != 0xFFFFFFFF );