조각코드! C/C++ 에서는 참으로 복잡 시럽게 코딩을 해줘야 했지만.. 이역시 간단하게 처리가 된다. =ㅂ=



using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ToolboxTestApp2
{
    class Program
    {
         static void Main(string[] args)
        {
            DirectoryInfo dir = new DirectoryInfo(Directory.GetCurrentDirectory());
            FileInfo[] filesInfo = dir.GetFiles();
            // for 아 c/c++ 같어~
            for (int i = 0; i < filesInfo.Length; ++i)
            {
                System.Console.WriteLine(filesInfo[i].Name);
            }
            // foreach 사용해서 출력~ 
            foreach (FileInfo each in filesInfo)
            {
                System.Console.WriteLine(each.Name);
            }
        }
    }
}
Posted by ngcbbs
,

간단하게 C/C++ 을 알고 있는 사용자에게 설명하면 함수 포인터 같은녀석! 이라고 이야기 할 수 있겠다.

다만 사용 방법이나 다중 위임의 형태를 C/C++ 에서 구현하기 위해서는 잡다한 코드가 더 추가되어야 하지만 정말 간편하게 다중 위임으로 처리가 가능하다.

delegate 키워드를 사용.


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ToolboxTestApp1
{
    class Program
    {
        // 위임이 무엇인고??
        public delegate int Printer(string msg); // 함수 포인터 처럼 함수 바디는 필요 없다.

        public static int Printer_My1(string msg)
        {
            System.Console.WriteLine("Printer_My1 = " + msg);
            return 1;
        }

        public static int Printer_My2(string msg)
        {
            System.Console.WriteLine("Printer_My2 = " + msg);
            return 2;
        }

        static void Main(string[] args)
        {
            Printer _printer = new Printer(Printer_My1);
            _printer += new Printer(Printer_My2); // += 연산자를 통해서 다중 위임 처리.

            _printer("한가한가~"); // _printer 에 위임된 프린터가 동작한다.
        }
    }
}


Posted by ngcbbs
,

아주 기초적인 프레임 생성 코드! wxFromBuilder 등에서 기본적인 배치및 이벤트 헨들러 지정을 해도 app 관련 코드는 생성해 주지 않으므로 일단 기본 코드가 있으면 좋다!...


#include "wx/wx.h"

//////////////////////////////////////////////////////////////////////////
// wxWidgets 최신 버전 다운로드
// http://www.wxwidgets.org/downloads/
// Current Stable Release: 2.9.3
// Previous Stable Release: 2.8.12
// * 다운로드 페이지에는 2.9.3 이 최신버전이 아니지만 2.9.3이 최신버전이 맞음.
//   다음 버전은 2.9.4 일것이고 다음은 2.9.5 혹은 3.0 으로 된것이라고 함.
//   3.0 에서는 윈도우 메트로 ui 도 지원할지도 모르겠음.(이건 추측)

//////////////////////////////////////////////////////////////////////////
// 컴파일 할때 설정해 줘야 하는것들 (비주얼 스튜디오 기준)
// * 추가 include 폴더 지정.
//	[wxWidget폴더]/include
//	[wxWidget폴더]/include/msvc
// * 추가 library 폴더 지정.
//	[wxWidget폴더]/lib/vc_lib			<- static lib 로 링크하는 경우.
//  [wxWidget폴더]/lib/vc_dll			<- dynamic dll 로 링크하는 경우. (해당 dll 을 실행파일 경로에 복사해줘야함)

//////////////////////////////////////////////////////////////////////////
// BaseFrame
class CBaseFrame : public wxFrame
{
public:
	CBaseFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title)
	{
		/*
		자식 윈도우의 이벤트 처리는 아래와 같은 형태로 직접 연결.
		// Connect Events
		mGridSizeCombo->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(NGCEditorFrame::OnSelected), NULL, this);
		mGridSizeCombo->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(NGCEditorFrame::OnEnter), NULL, this);
		*/
	}

	virtual ~CBaseFrame() 
	{
		/*
		자식 윈도우 이벤트 연결이 되었다면 윈도우 삭제시 연결 해제 해주자.
		// Disconnect Events
		mGridSizeCombo->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(NGCEditorFrame::OnSelected), NULL, this);
		mGridSizeCombo->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(NGCEditorFrame::OnEnter), NULL, this);
		*/
	}

	void OnSize(wxSizeEvent& event)
	{
		wxFrame::OnSize(event);
	}

	DECLARE_EVENT_TABLE()
};

// CBaseFrame 이벤트 헨들러 지정
BEGIN_EVENT_TABLE(CBaseFrame, wxFrame)
	EVT_SIZE(CBaseFrame::OnSize)
END_EVENT_TABLE()

//////////////////////////////////////////////////////////////////////////
// BaseApp
class CBaseApp : public wxApp
{
public:
	CBaseApp() : pFrame(0) {}

	virtual ~CBaseApp() {}

	bool OnInit()
	{
		if (!wxApp::OnInit())
			return false;

		pFrame = new CBaseFrame(wxT("기본윈도우"));
		pFrame->SetClientSize(640, 480);
		pFrame->Center();
		pFrame->Show();

		SetTopWindow(pFrame);

		return true;
	}

	int OnRun()
	{
		return wxApp::OnRun();
	}

	int OnExit()
	{
		return wxApp::OnExit();
	}

private:
	CBaseFrame* pFrame;

};

// CBaseApp 구현부
IMPLEMENT_APP(CBaseApp)

Posted by ngcbbs
,

다음과 같은 코드를 통해서 확인할 수 있다.



void ErrorMessageBox(DWORD dwError)
{
	LPVOID lpMsg = NULL;
	DWORD dwFormat = FORMAT_MESSAGE_ALLOCATE_BUFFER |
					 FORMAT_MESSAGE_FROM_SYSTEM |
					 FORMAT_MESSAGE_IGNORE_INSERTS;
	DWORD dwLanguage = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);

	if (!FormatMessage(dwFormat, NULL, dwError, dwLanguage, 
		(LPTSTR)&lpMsg, 0, NULL))
	{
		return;
	}

	MessageBox(NULL, (LPCTSTR)lpMsg, L"Error", MB_OK | MB_ICONINFORMATION);
	
	LocalFree(lpMsg);
}


Posted by ngcbbs
,

SQLite3 다운로드 : http://sqlite.org/download.html

SQLite3 라이센스Public Domain

기본적으로 다운로드 받은 소스에서 sqlite3.c / sqlite3.h / sqlite3ext.h 만 프로젝트에 포함시키면 SQLite3 를 사용할 수 있다.

SQLite3 의 장점. 작고, 설정 필요 없이 사용가능하고, 단일 파일에 모든 내용이 저장되며, 여러 플랫폼에서 하나의 db 파일을 사용할 수 있다.

SQLite3 를 통해 작업중인 맵에디터에 리소스 관리 부분을 붙여보기 위해서 사용법을 익히는중..(@_@b) <>


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

#include "sqlite3/sqlite3.h"

static int callback(void* notUse, int argc, char** argv, char** colName)
{
	// sql 구문에 의해서 명령어 처리시 사용되는 콜백함수.
	// argc : 데이터 갯수.
	// argv : 데이터 항목.
	// colName : 데이터 항목의 분류명.

	/*
	 * 예제 db 테이블...
	 * /'''''''' argc '''''''''\
	 * +--------------+---------+
	 * | char name(80)| int agc | <-- colName
	 * +--------------+---------+
	 * | 이름1        | 10      | <-- argv
	 * | 이름11       | 20      |
	 * +--------------+---------+
	 */
	for (int i = 0; i < argc; ++i)
	{
		printf("%s = %s\n", colName[i], argv[i] ? argv[i] : "(null)");
	}

	printf("\n");
	return 0;
}

#define CHECK_QUIT(INFO, RET) \
	if (ret != SQLITE_OK) { fprintf(stderr, "'%s' error\n", INFO); return RET; }
#define CHECK(INFO) \
	if (ret != SQLITE_OK) { fprintf(stderr, "'%s' error\n", INFO); }
#define ERROR(INFO) \
	fprintf(stderr, "%s : '%s'\n", INFO, sqlite3_errmsg(db));

int main(int argc, char** argv)
{
	sqlite3* db;
	char* errMsg = NULL;
	char* filename = "test.db"; /// 해당 파일이 없는 경우 sqlite3_open 함수 호출시 빈 db 파일 생성.
	char* createTableQuery = "create table test_table(name text(20), age int);";
	char* insertDataQuery = "insert into test_table(name, age) values('이름', 10);";
	char* requestTableQuery = "select * from test_table;";

	int ret = sqlite3_open(argv[1], &db);

	if (ret == SQLITE_OK)
	{
		/// 1. 테스트 테이블 생성
		ret = sqlite3_exec(db, createTableQuery, callback, 0, &errMsg);
		CHECK("createTableQuery");

		/// 2. 테스트 테이블에 데이터 삽입
		ret = sqlite3_exec(db, insertDataQuery, callback, 0, &errMsg);
		CHECK("insertDataQuery");

		/// 3. 테스트 테이블 요청
		ret = sqlite3_exec(db, requestTableQuery, callback, 0, &errMsg);
		CHECK("requestTableQuery");

		/// 4. sqlite3_exe 함수와 callback 함수를 사용하지 않고 데이터 읽기. (3단계와 같은 동작)
		{
			sqlite3_stmt* stmt;

			ret = sqlite3_exec(db, "BEGIN", 0, 0, 0);
			CHECK("트랜잭션 걸기");

			if (sqlite3_prepare(db, requestTableQuery, -1, &stmt, NULL) == SQLITE_OK)
			{
				while (sqlite3_step(stmt) == SQLITE_ROW)
				{
					/// windows 콘솔창에서 한글이 출력되지 않으면.. setlocale(LC_ALL, "") 함수를
					/// 통해서 출력되도록 할 수 있다.
					wprintf(L"name:%s, age:%s\n",
							(char*)sqlite3_column_text(stmt, 0),
							(char*)sqlite3_column_text(stmt, 1));
				}
			}
			else
			{
				ERROR("에러");
			}

			ret = sqlite3_exec(db, "END", 0, 0, 0);
			CHECK("트랜잭션 해제");

			sqlite3_finalize(stmt);
		}

		sqlite3_close(db);
	}
	else
	{
		ERROR("데이터베이스 열기 실패");
		sqlite3_close(db);
		return -1;
	}

	return 0;
}


Posted by ngcbbs
,
재배포 패키지 버전 문제 발생시

- '응용 프로그램 구성이 올바르지 않기 때문에 이 응용 프로그램을 시작하지 못했습니다. 이 문제를 해결하려면 응용 프로그램을 다시 설치하십시오.'

위와 같은 에러와 함께 실행이 되지 않습니다.

- 기타 에러 혹은 Microsoft Virtual PC등에서 바로 죽어 버리는 문제 혹은 잘못된 주소를 참조 했다거나... 예외가 발생했다는 에러는 프로그램의 오류
가능성이 높다. 이때에는 release 빌드에 *.pdb 파일을 같은 폴더에 넣고 디버그 해보면 어느 함수에서 죽었는지 알 수 있다.
( 비주얼 스튜디오가 깔려 있다면... 없는 경우에는 콜스텍을 덤프해주도록 처리하면 문제가 없겠다. )

-----------------------------------------------------------------------------------------------------------------------------------------------

publicKeyToken="1fc8b3b9a1e18e3b" 의 의미는 어떤 버전(세부 업데이트까지가 아니고 그냥 대~~충 dx9 라고 부르는것 처럼.. 이해하믄 되겠다.)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.6161" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

위의 manifest 는 정상이다.

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1

을 wxWidgets-2.9.3 / squish-1.10 / 프로그램에 모두에 적용하고 플그램을 빌드해도 위와같이 나온다. (추측, 아마 다른 라이브러리나 dll 이

9.0.21022.8 버전을 참조하고 있어서 그런듯하다.

그리고 _BIND_TO_CURRENT_VCLIBS_VERSION 설정이 잘 적용되고 있는지 확인해 보고 싶다면.

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include 혹은 vc2008 설치된 경로참조 crtassem.h 파일을 열어서

참고해 보는게 좋겠다.

#ifndef _CRT_ASSEMBLY_VERSION
#if _BIND_TO_CURRENT_CRT_VERSION
#define _CRT_ASSEMBLY_VERSION "9.0.30729.6161"
#else
#define _CRT_ASSEMBLY_VERSION "9.0.21022.8"
#endif
#endif

참고로 나는 저렇게 되어 있었고 wxWidgets-2.9.3 / squish-1.10 / 프로그램에서 항상

#define _CRT_ASSEMBLY_VERSION "9.0.30729.6161"

가 추가되는것을 확인했음에도... 위에 나온 9.0.21022.8 버전에 대한 의존성을 가지고 있었다.

-----------------------------------------------------------------------------------------------------------------------------------------------

menifest 파일이 없을때(파일에 포함된경우 그리고 비주얼 스튜디오가 설치되어 있다면) mt.exe 파일로 생성해 볼 수 있다. (당연히 비주얼 스튜디오 프롬프트에서 실행)

mt.exe -inputresource:test.exe -out:test.exe.menifest

위와같이 하면 되겠다.

-----------------------------------------------------------------------------------------------------------------------------------------------

결론! : 내가 프로그램에 버그를 심었던 것!! 그로 인해 vcredist 를 오해하고.. 삽질을 열씸히 했던 것이었음.
    (멤버 변수는 항상 초기화 해야 한다는것을 알았지만 이번에 깜빡! 정말로 깜빡했다..--a)
첨언! : Windows7 에서는 몇가지 예외들에 대해서 관대한 편이다. Windows Xp 에서만 실행이 안되고 초반부에 말한 예외 관련된 에러 메세지가 보인다면
자신의 소스 코드부터 찬찬히 그리고 디버깅 해보는것이 순서이다.
Posted by ngcbbs
,
비주얼 스튜디오를 통한 툴 혹은 게임등을 제작한뒤 개발자 컴퓨터에서 아무런 문제 없이 동작하던 프로그램이 테스트를 위해 복사 혹은 설치형태로 프로그램을 배포한뒤 만나게 되는 문제가 바로 재배포 문제인데요...

이전에 어렵사리 맞춰놓은 재배포 패키지로 작업하던 툴이 시간이 흐른뒤 수정작업을 하고나니 다른 컴퓨터에서 실행이 되지 않는다고하면.. 엄청난 스트래스가!! 아무튼 아직도 고민중인 내용이지만 일단 이전 내용과 지금 찾아서 테스트 하는 내용을 정리 해본다.

1. 외부 라이브러리의 경우 항상 같은 컴파일 옵션 유지.
2. 특정 버전(최신 현재 개발 컴퓨터에 깔린 최신 버전을 말함)의 재배포 프로그램을 사용하도록 강제하는  define 이 있다.

#define _BIND_TO_CURRENT_CRT_VERSION 1
#define _BIND_TO_CURRENT_ATL_VERSION 1
#define _BIND_TO_CURRENT_MFC_VERSION 1
#define _BIND_TO_CURRENT_OPENMP_VERSION 1

각각 crt atl mfc openmp 등등 해당하는 재배포 부분을 최신의 것을 사용하게 하는것이도 이것 전체를 하나의  define 으로도 설정 가능하다

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1

이러한 define 을 보통 외부 라이브러리들과 배포할 프로그램 프로젝트 설정에 선언해 놓으면 일률적으로 하나의 버전을 사용하는 라이브러리/프로그램이 만들어 진다고 한다.


하지만!!!


해당 부분을 적용해 본 결과 최신의 재배포 패키지에 대한 종속성은 변경 되었지만... 이전 버전이 하나 추가되어 이상한 상태로 현재 해결이 안되고 있다. (물론 windows 7 에서는 별다른 이상없이 이전 재배포 패키지가 설치된 pc 에서 문제가 없었지만 xp 에서 실행이 안되는 문제가 있음)


그리고 구글님의 도움으로 외국사이트에서 찾은 자세한(?) 글이 있었는데 그것은 회사에... 곧 추가하도록 하겠음.



근데... 왜 갑자기 다시 재배포 문제가 발생한 것인지... 아마도 범인은 자동 업데이트?! 

구글링을 통해 알아본 내용은 몇가지 조건에 따라 나타나는 증상까지 설명이 되어 있어서 찬찬히 보고 적용해 보기로 하고...

msdn 에서 한글로 번역해 주신 참고 주소 추가!~

http://msdn.microsoft.com/ko-kr/library/ms235299(v=vs.90).aspx  

하지만 잘 모르겠다-ㅅ- 뭔가 둥글둥글하게 지나가는거 같기도 하고 아! 이거야 하는 느낌이 날정도로 살펴보진 않았으니.. 




기존에 배포하던 툴의 manifest 정보. ( 9.0.21022 에 해당하는 vcredist_x86 을 함께 배포해 문제가 해결되었었다. )

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly> 



새로 컴파일되어 생성된 manifest 정보. ( 9.0.30729.6161 가 추가되었다. 음.. 해당 vcredist_x86도 함께 제공 했던거 같은데 실행에 문제가 있음.)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.6161" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! define 추가를 잘못했었네!? 일단 되나 확인부터
_BIND_TO_CURRENT_VCLIBS_VERSION=1 이거다

_BIND_TO_CURRENT_VCLIBS=1 <-- 왜 이래놨을까;;
Posted by ngcbbs
,
#define _CRT_SECURE_NO_WARNINGS

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

char szComputerName[17] = {0,};
char szUserName[17] = {0,};

void main()
{
	const char* dat_file = "prebuild.dat";
	const char* build_file = "build.h";
	FILE* fp = NULL;
	fp = fopen( dat_file, "rb" );
	if ( NULL == fp )
	{
		int init_build = 0;
		fp = fopen( dat_file, "wb" );
		fwrite(&init_build, sizeof(int), 1, fp);
		fclose( fp );
		fp = fopen( dat_file, "rb" );
	}

	int new_build = 0;
	fread(&new_build, sizeof(int), 1, fp);
	fclose( fp );

	new_build++;

	fp = fopen( dat_file, "wb" );
	fwrite(&new_build, sizeof(int), 1, fp);
	fclose( fp );

	fp = fopen( build_file, "wt" );
	fprintf(fp, "#define __BUILD_COUNT__ %d\n", new_build);
	DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1;		
	::GetComputerName(szComputerName, &nSize);
	::GetUserName(szUserName, &nSize);
	fprintf(fp, "#define __BUILD_COMPUTER__ L\"%s\"\n", szComputerName);
	fprintf(fp, "#define __BUILD_USER__ L\"%s\"\n", szUserName);
	time_t timer;
	struct tm *t;
	timer = time(NULL);
	t = localtime(&timer);
	fprintf(fp, "#define __BUILD_TIME__ L\"%d월 %d일 %d시 %d분\"\n", t->tm_mon+1, t->tm_mday, t->tm_hour+1, t->tm_min);
	fclose(fp);
}
- 개선할 점 : 옵션처리( ansi / unicode / 추가 텍스트 ).
Posted by ngcbbs
,