C++ 빌드 후 이벤트 에러 발생 ( MSB3073  :VCEnd 에러 )



파일 경로에서 공백이 있는 경우 발생


프로젝트 - 속성 - 구성 속성 - 빌드 이벤트 - 빌드 후 이벤트 - 명령줄을 수정


변경전

copy $(ProjectDir)Text.txt $(OutputPath)


변경후 (따옴표로 감싸 주면 에러 해결)

copy "$(ProjectDir)Text.txt" "$(OutputPath)"



Posted by seanpaul
,

C++ 디버그(Debugging)시 STL Code Into Step 방지



비주얼 스튜디오 버전에 맞는 폴더(본문은 Visual Studio 2013)


C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Packages\Debugger\Visualizers


default.natstepfilter 필터에 아래 코드를 복사 해서 저장.

Notepad, EditPlus 등등 ( 관리자 모드 실행 )


<?xml version="1.0" encoding="utf-8"?>

<StepFilter xmlns="http://schemas.microsoft.com/vstudio/debugger/natstepfilter/2010">


<Function><Name>std::.*</Name><Action>NoStepInto</Action></Function>


  <Function><Name>__security_check_cookie</Name><Action>NoStepInto</Action></Function>  

  <Function><Name>operator new</Name><Action>NoStepInto</Action></Function>

</StepFilter>





Posted by seanpaul
,

Visual Studio 2013 Boost Library Compile




1. 부스트 라이브러리 최신 버전이나 필요한 버전을 다운 받는다.

- 이 글 작성시 부스트 최신 버전 : 1_58_0 


부스트 공식 홈( http://www.boost.org ) 또는 

SourceForge 다운로드  http://sourceforge.net/projects/boost/files/


컴파일을 하지 않고 바로 사용 할려면 컴파일된 x32, 또는 x64 파일을 다운

http://sourceforge.net/projects/boost/files/boost-binaries/1.58.0/

Boost_1_58_0-bin-msvc-all-32-64.7z 1.3GB (x32, x64 비주얼 스튜디오 모든 버전 포함)


Visual Studio 2013 크로스 컴파일러를 설치하면  
여러 가지 커맨드 프롬프트 제공 합니다. ( Itanium 버전은 인텔의 개발 중지 발표로 생략)


x64 크로스 Tools 명령 프롬프트에서는 x86환경에서 x64 컴파일 가능.

x86, x64 네이티브에서는 각 각  x32 , x64 컴파일 가능.


*** 미리 컴파일된 버전을 사용하지 않고 직접 컴파일해서 사용 하고자 한다면 ***


Boost 라이브러리는 두가지 방법으로 컴파일 할 수 있는데,

헤더 파일과 라이브러리를 생성하는 방법과, 라이브 러리를 생성 하는 방법이 있습니다.


처음 설치 한다면 헤더(Header)와 라이브러리(Library)가 필요 하므로 install 옵션을 쓰고 

추가적으로 라이브러리(Library)가 필요하다면 stage를 쓰면 됩니다.


부스트 라이브러리 루트 폴더에 boostrap.bat 실행해서 b2.exe와 bjam.exe를 생성 합니다.

2개다 같은 일을 하지만 여기서는 b2.exe으로 설명 합니다.

b2 [options] [properties] [install|stage]

VS 2013 기준(msvc-12.0), VS 2012 : msvc-11.0)


--stagedir (라이브러리 파일이 있는 stage 폴더내에 복사

--libdir을 지정 해주면 원하는 폴더로 복사( --libdir="C:\Boost\lib" )

--includedir 위 와 마찬가지( --includedir="C:\Boost\include" )

-j n - CPU 멀티 코어 사용 ( n : 코어 갯수 지정 )


x32 라이브러리

/MT, /MTd (멀티 스레드 릴리즈, 멀티 스레드 디버그) : 정적 라이브러리 생성( .LIB )

b2  --stagedir=stage32 --toolset=msvc-12.0 -j 4 runtime-link=static


/MD, /MDd (멀티 다이나믹, 멀티 다이나믹 디버그  ): 동적 라이브러리 생성( .DLL )

b2  --stagedir=stage32 --toolset=msvc-12.0 -j 4 runtime-link=shared 


x64 라이브러리

/MT, /MTd (멀티 스레드 릴리즈, 멀티 스레드 디버그) : 정적 라이브러리 생성

b2  --stagedir=stage64 address-model=64 --toolset=msvc-12.0 -j 4 runtime-link=static


/MD, /MDd

b2  --stagedir=stage64 address-model=64 --toolset=msvc-12.0 -j 4 runtime-link=shared


컴파일 결과파일 이름(Naming) 규칙

- lib 접두사 - Win32에서 Static 라이브러리에 붙음.

- boost - 접두사 모든 파일 앞에 붙음.

- vc120 - 비주얼 스튜디오 버전별로( 2012 : vc110, 2010 : vc100 )


- mt - Shared 멀티 스레드용(multi-threading) 릴리즈 버전 

- mt-gd Shared 방식으로 멀티 스레드용(multi-threading) 디버그 버전

- mt-s Static 방식으로 릴리즈

- mt-sgd  Static multi-threading 디버그 버전

- 1_58 - 부스트 버전.

- .lib - 확장자




컴파일 예제 :

C:\Boost에 Visual Studio 2013버전 x32, x64 디버그, 릴리즈 

싱글, 멀티스레딩(정적, 동적 라이브러리)를 멀티코어 4개로 컴파일


b2  --libdir="C:\Boost\lib" --libinclude="C:\Boost\include"

 --toolset=msvc-12.0 variant=debug,release address-model=32,64 

threading=single,multi -j 4 runtime-link=static,shared 


컴파일 결과 : C:\Boost\Lib, C:\Boost\Include 생성 lib 폴더내에 .lib, .dll 파일 생성




Posted by seanpaul
,

MinGW용 부스트 라이브러리(Boost Library)와 이클립스(Eclipse) 




윈도우(Windows)에서 C++ 사용할 때  비주얼 스튜디오 Visual Studio C++ 이나 

CDT 이클립스(Eclipse)를 보통 사용 하는데,


Visual Studio C++은 부스트 이용에 큰 불편함이 없는데, CDT 이클립스를 사용할 때는 

링커에서 링크 하지 못해서 실행 파일이 생성 되지 않습니다.


부스트 라이브러리(Boost Library)가 설치된(Install) Include 폴더와 Lib 폴더를 지정 해줘도 

계속 에러가 생겨서 해결을 못하고 있었던 차에 해결 방법을 알아내어서 해결 방법을 올려 봅니다.


MinGW 패스를 지정 하면서 기존 패스도 유지

Set Path=C:\Mingw\Bin;%PATH%


부스트 라이브러리가 아래에 있다면

C:\Build_Boost\boost_1_58_0\tools\build\src\engine


MinGW용 b2.exe bjam.exe 생성

C:\Build_Boost\boost_1_58_0\tools\build\src\engine\build.bat mingw


생성된 b2.exe와 bjam.exe Boost 루트 폴더로 복사 

기존 Visual Studio용 b2.exe bjam.exe 있다면 백업하거나 다른 이름으로 변경


*** 컴파일 하기 ***

처음 설치시 헤더와 라이브러리를 생성 하기 위해서 install 옵션 사용

b2 tool-set=gcc --build-type=complete install -j 4


라이브러리만 생성 시킬때는 stage 옵션 사용

b2 tool-set=gcc --build-type=complete stage -j 4


부분 파일만 컴파일 한다면

b2 tool-set=gcc --build-type=complete --with-filesystem  install -j 4





*** 이클립스에서 Boost Library 셋팅 하기 ***


 

이클립스에서 C++ 프로젝트(Exam_Boost_Rambda)를 만들고 C++ 파일 생성 아래 코드 복사


#include <iostream>

#include <boost/lambda/lambda.hpp>

#include <iterator>


using namespace std;

using namespace boost::lambda;


int main()

{

cout << "콘솔에 숫자입력 (종료시 z 입력)" << endl;

cout << "예제 : 1 2 3 입력하면  * 3을 한 결과 3 6 9 출력 " << endl;

typedef istream_iterator<int> in;


for_each(in(cin), in(), cout << (_1 * 3) << " ");

cout << endl;


return 0;

}


Exam_Boost_Rambda 프로젝트 - 속성에서 

아래와 같이 개발 컴퓨터의  부스트 라이브러리가 설치 되어 있는 경로 수정.







*** 이클립스 셋팅중에서 제일 중요한 부분  ***




MinGW C++ Linker - Libraries(-i)에는 라이브러리의 접두사 lib를 빼고 파일 이름만 입력(확장자 불필요)


Library search path(-L) 에 부분에는 부스트 lib 폴더 입력, 컴파일 에러시 MinGW lib 폴더 추가 입력.


Posted by seanpaul
,

CppAutomateExcel.zip

AutoMation CPP Code
#include "stdafx.h"
#include  // OLE2 Definitions
#include 

// AutoWrap() - Automation helper function...
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {
	// Begin variable-argument list...
	va_list marker;
	va_start(marker, cArgs);

	if (!pDisp) {
		MessageBox(NULL, L"NULL IDispatch passed to AutoWrap()", L"Error", 0x10010);
		_exit(0);
	}

	// Variables used...
	DISPPARAMS dp = { NULL, NULL, 0, 0 };
	DISPID dispidNamed = DISPID_PROPERTYPUT;
	DISPID dispID;
	HRESULT hr;
	char szName[200];


	// Convert down to ANSI
	WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);

	// Get DISPID for name passed...
	hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
	if (FAILED(hr)) {
		//sprintf(buf, "IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx", szName, hr);
		//MessageBox(NULL, buf, "AutoWrap()", 0x10010);
		_exit(0);
		return hr;
	}

	// Allocate memory for arguments...
	VARIANT *pArgs = new VARIANT[cArgs + 1];
	// Extract arguments...
	for (int i = 0; iInvoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
	if (FAILED(hr)) {
		//sprintf(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr);
		//MessageBox(NULL, buf, "AutoWrap()", 0x10010);
		_exit(0);
		return hr;
	}
	// End variable-argument section...
	va_end(marker);

	delete[] pArgs;

	return hr;
}

int main()
{
	// Initialize COM for this thread...
	CoInitialize(NULL);

	// Get CLSID for our server...
	CLSID clsid;
	HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);

	if (FAILED(hr)) {

		::MessageBox(NULL, L"CLSIDFromProgID() failed", L"Error", 0x10010);
		return -1;
	}

	// Start server and get IDispatch...
	IDispatch *pXlApp;
	hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pXlApp);
	if (FAILED(hr)) {
		::MessageBox(NULL, L"Excel not registered properly", L"Error", 0x10010);
		return -2;
	}

	/* Make it visible (i.e. app.visible = 1)
	{

	VARIANT x;
	x.vt = VT_I4;
	x.lVal = 1;
	AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlApp, L"Visible", 1, x);
	}
	*/

	// Get Workbooks collection
	IDispatch *pXlBooks;
	{
		VARIANT result;
		VariantInit(&result);
		AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"Workbooks", 0);
		pXlBooks = result.pdispVal;
	}

	// Call Workbooks.Open() to get a new workbook...
	IDispatch *pXlBook;
	{
		VARIANT vtFileName;
		vtFileName.vt = VT_BSTR;
		vtFileName.bstrVal = SysAllocString(L"C:\\Users\\UserName\\Desktop\\test.xls");

		VARIANT result;
		VariantInit(&result);
		AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, L"Open", 1, vtFileName);             // reversed order is using more options
		pXlBook = result.pdispVal;
	}

	// Get ActiveSheet object
	IDispatch *pXlSheet;
	{
		VARIANT result;
		VariantInit(&result);
		AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"ActiveSheet", 0);
		pXlSheet = result.pdispVal;
	}

	// pXlBook->SaveAs
	{
		// Convert the NULL-terminated string to BSTR.
		VARIANT vtFileName;
		vtFileName.vt = VT_BSTR;
		vtFileName.bstrVal = SysAllocString(L"C:\\Users\\UserName\\Desktop\\test_sheet1.csv");

		VARIANT vtFormat;
		vtFormat.vt = VT_I4;
		vtFormat.lVal = 6;     // XlFileFormat::xlCSV

		// If there are more than 1 parameters passed, they MUST be pass in 
		// reversed order. Otherwise, you may get the error 0x80020009.
		AutoWrap(DISPATCH_METHOD, NULL, pXlBook, L"SaveAs", 2, vtFormat,
			vtFileName);

		VariantClear(&vtFileName);
	}

	//Changing the ActiveSheet    
	{
		{
			VARIANT itemn;
			itemn.vt = VT_I4;
			itemn.lVal = 2;

			VARIANT result;
			VariantInit(&result);
			AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"Worksheets", 1, itemn);
			pXlSheet = result.pdispVal;
		}

		{
			VARIANT result;
			VariantInit(&result);
			AutoWrap(DISPATCH_METHOD, &result, pXlSheet, L"Activate", 0);
		}
	}

	// pXlBook->SaveAs
	{
		// Convert the NULL-terminated string to BSTR.
		VARIANT vtFileName;
		vtFileName.vt = VT_BSTR;
		vtFileName.bstrVal = SysAllocString(L"C:\\Users\\UserName\\Desktop\\test_sheet2.csv");

		VARIANT vtFormat;
		vtFormat.vt = VT_I4;
		vtFormat.lVal = 6;     // XlFileFormat::xlCSV

		// If there are more than 1 parameters passed, they MUST be pass in 
		// reversed order. Otherwise, you may get the error 0x80020009.
		AutoWrap(DISPATCH_METHOD, NULL, pXlBook, L"SaveAs", 2, vtFormat,
			vtFileName);

		VariantClear(&vtFileName);
	}

	// Set .Saved property of workbook to TRUE so we aren't prompted
	// to save when we tell Excel to quit...
	{
		VARIANT x;
		x.vt = VT_I4;
		x.lVal = 1;
		AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlBook, L"Saved", 1, x);
	}

	// Tell Excel to quit (i.e. App.Quit)
	AutoWrap(DISPATCH_METHOD, NULL, pXlApp, L"Quit", 0);

	// Release references...
	pXlSheet->Release();
	pXlBook->Release();
	pXlBooks->Release();
	pXlApp->Release();

	// Uninitialize COM for this thread...
	CoUninitialize();

	return 0;
}
Posted by seanpaul
,