Visual Studio 에서 C++ 로 사용하기 위한 protobuf 설치

구글 protobuf 를 새로 개발하고 있는 서버에 적용해보려고 찾아보았다. 설치에 대한 링크는 구글 Protocol Buffer VS 설치라는 글이 보였는데 2015년에 작성된 글이라 그런지 지금과 맞지 않았다. vsproject라는 폴더가 있다고 하는데 이런 폴더 자체가 없었으니.

그래서 새로 빌드해보기로 하고 그 과정을 정리해본다.

구글 protobuf 홈페이지로 이동한다.

https://github.com/google/protobuf/

C++에서 사용하기 위해 Protobuf Runtime Installation 항목으로 이동했더니 src 폴더로 가보라고 되어있다.

https://github.com/google/protobuf/tree/master/src 에 가서 밑의 README.md 파일 내용을 읽어보니 C++ Installation – Windows 항목이 있어 이 내용을 읽어본다.

If you only need the protoc binary, you can download it from the release page:

https://github.com/google/protobuf/releases

In the downloads section, download the zip file protoc-$VERSION-win32.zip. It contains the protoc binary as well as public proto files of protobuf library.

To build from source using Microsoft Visual C++, see cmake/README.md.

To build from source using Cygwin or MinGW, follow the Unix installation instructions, above.

안내문에서 지시하는대로 cmake/README.md 파일을 열어보았다.

https://github.com/google/protobuf/blob/master/cmake/README.md

환경설정을 진행하고 cmake를 다운로드한다. 구글에서 cmake 를 검색하여 Win64용의 cmake 프로그램을 설치.

이미 윈도우용 git이 설치되어 있으므로 VS2015용 개발자 명령 프롬프트창을 열고 라이브러리를 모아놓은 폴더에 가서 소스를 다운 받는다. 릴리즈 버전은 지금 최신버전인 3.5.0 으로 받았다. 개발자 명령 프롬프트가 아니라 cmd 창으로 열면 컴파일러인 cl.exe가 인식이 안되기 때문에 오류가 난다.

git clone -b v3.5.0 https://github.com/google/protobuf.git

폴더가 만들어지면 그 안으로 들어가서 gmock 도 받는다.

git clone -b release-1.7.0 https://github.com/google/googlemock.git gmock

그 안으로 들어가 googletest 코드도 받는다.

git clone -b release-1.7.0 https://github.com/google/googletest.git gtest

protobuf를 받은 위치에서 cmake 라는 폴더를 들어간다. 이 밑에 build 라는 디렉토리를 만들고 그 밑에 debug, release, solution 이라는 3개의 디렉토리를 만든다.

debug 폴더로 이동하여 다음 명령 실행

cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=../../../../install ../..

release 폴더로 이동하여 다음 명령 실행

cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../../../../install ../..

solution 폴더로 이동하여 다음 명령 실행

cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_INSTALL_PREFIX=../../../../install ../..

설명서에는 Visual Studio 12 2013 으로 설명되어 있지만 난 VS2015를 사용하므로 그에 맞도록 수정했다.

빌드하기 위해 release 폴더혹은 debug 폴더에서 nmake 명령과 nmake check 명령을 차례대로 실행한다.

nmake check 이후 아무 문제 없다면 nmake install 을 진행하면 되나 나같은 경우에는 아래와 같은 에러메시지가 떴다.

[----------] Global test environment tear-down
[==========] 2009 tests from 194 test cases ran. (54957 ms total)
[  PASSED  ] 2001 tests.
[  FAILED  ] 8 tests, listed below:
[  FAILED  ] CommandLineInterfaceTest.Win32ErrorMessage
[  FAILED  ] BootstrapTest.GeneratedDescriptorMatches
[  FAILED  ] CsharpBootstrapTest.GeneratedCsharpDescriptorMatches
[  FAILED  ] RubyGeneratorTest.GeneratorTest
[  FAILED  ] TokenizerTest.ParseString
[  FAILED  ] TextFormatMapTest.Sorted
[  FAILED  ] TextFormatTest.Basic
[  FAILED  ] TextFormatExtensionsTest.Extensions

이 에러메시지를 해결하기 위해 구글에 검색해봤지만 딱히 좋은 대안은 찾지 못했다. 자연스러운 에러메시지(?)라는 글도 있긴했다.

빌드가 완료되면 lib 파일들과 헤더파일들이 생성되는데 이 생성되는 위치가 protobuf 폴더 바로 위의 install 이라는 폴더에 생성된다.

lib 파일을 비주얼스튜디오에 연결하고 헤더파일을 가져다 사용하면 된다. 이에 대한 내용은 Protobuf 실제 사용글을 참조하면 된다. 아니면 검색엔진에 검색해봐도 많이 나온다.

자세한 사용방법은 protobuf 홈페이지에서. https://developers.google.com/protocol-buffers/docs/cpptutorial

Google Breakpad 설치 (1)

Google Breakpad를 사용하기 위한 방법에 대해 고생했던 것을 정리한다.

윈도우와 리눅스에서 동시에 사용할 수 있는 서버프로그램을 개발하고 있는데 윈도우에서야 미니덤프를 이용하여 덤프를 남기면 되지만 리눅스에서는 coredump라는 생소한 시스템을 이용해야해서 아예 크로스플랫폼 덤프 시스템을 찾다가 구글브레이크패드를 이용해봐야겠다는 생각에 시작했다.

https://chromium.googlesource.com/breakpad/breakpad 로 이동한다. 많은 블로그에서 http://google-breakpad.googlecode.com/svn/trunk 에서 체크아웃 받으라고 나와있지만 이것은 옛날 정보이다. 현재를 기준으로 사이트는 이동되었으며 SVN이 아니라 GIT을 이용해야 소스를 받을 수 있다.

GIT을 이용하면 되긴하나 귀찮으므로 master 브랜치를 선택하고 tgz로 압축된 파일을 받는다. 7zip을 이용하여 압축파일의 압축을 해제한다. 윈도우에서는 tgz 파일을 풀어서 tar 파일을 만들고 다시 또 한번 아카이빙을 풀어야한다. 물론 7zip 하나로 다 가능하다.

프로그램 설명서를 보기 위해 doc 폴더로 이동을 하면…. 아오… 마크다운 형식의 .md 파일만 잔뜩 들어있다. 브라우저로 볼 수가 없으므로 귀찮아서 그냥 구글 브레이크패드 홈페이지의 도큐먼트를 읽어보면 된다.

….근데 모르겠다.

대충 다른 블로그를 찾아보니 gyp 라는 시스템으로 비주얼스튜디오 솔루션 파일을 생성하면 되고…. gyp는 오픈소스이고… 구글 브레이크패드 소스를 받으면 포함되어 있단다. 근데 내가 보기에는 아무리 찾아도 gyp 라는 시스템이 포함되어 있진 않은 것 같다.

구글에 찾아보니 https://chromium.googlesource.com/external/gyp 에 가면 받을 수 있덴다.

가보니 또 git으로 받으라고 한다. 그냥 tgz 파일을 받고 압축을 푼다. 이 프로그램은 홈페이지에 도큐먼트도 없고 도움말도 없다. 뭐 어쩌라는건지…?

한참 애먹은 끝에… 일단 파이선을 설치하고(일단 최신버전인 3.5.2로 설치했다.), cmd 를 관리자권한으로 열고, python setup.py install 을 실행하면 된다는걸 알아냈다. 아오 짜증… 여튼 명령어를 입력하면 뭔가 텍스트가 촤르르륵 올라간다.

자 이제 다시 구글 브레이크패드를 다운 받은 폴더로 이동해서… src/build 에 있는 all.gyp를 실행하기 위해 gyp all.gyp 를 입력한다.

…..는 실패. 문법 오류가 있다고 한다.

그럼 다시 src/client/windows 의 breakpad_client.gyp 를 실행해본다.

…는 실패. 문법 오류가 있다고 한다.

파이선버전 문제인가 싶어서 3.5.2 버전을 다 지우고 2.7.12 버전으로 다시 설치하고 아까 all.gyp 명령을 다시 실행해본다.

안된다. 파이선을 재설치하는 과정에서 gyp가 다 삭제되었다. 다시 gyp를 설치한다.

다시 해봤는데 똑같다… 아오 힘들어.

http://yardbirds.tistory.com/107 를 보니

src\client\windows 폴더에서 ..\..\tools\gyp\gyp.bat breakpad_client.gyp 를 실행하면 솔루션 파일과 프로젝트 파일이 생성되는 것을 볼 수 있다.

라고 한다. 해봤다.

D:\Library\google-breakpad\src\client\windows>d:\Library\gyp-master\gyp.bat breakpad_client.gyp
gyp: Cycles in .gyp file dependency graph detected:
Cycle: breakpad_client.gyp -> sender\crash_report_sender.gyp -> breakpad_client.gyp
Cycle: unittests\client_tests.gyp -> breakpad_client.gyp -> unittests\client_tests.gyp
Cycle: unittests\client_tests.gyp -> crash_generation\crash_generation.gyp -> breakpad_client.gyp -> unittests\client_tests.gyp
Cycle: breakpad_client.gyp -> crash_generation\crash_generation.gyp -> breakpad_client.gyp
Cycle: unittests\client_tests.gyp -> handler\exception_handler.gyp -> crash_generation\crash_generation.gyp -> breakpad_client.gyp -> unittests\client_tests.gyp
Cycle: breakpad_client.gyp -> handler\exception_handler.gyp -> crash_generation\crash_generation.gyp -> breakpad_client.gyp
Cycle: breakpad_client.gyp -> tests\crash_generation_app\crash_generation_app.gyp -> handler\exception_handler.gyp -> crash_generation\crash_generation.gyp -> breakpad_client.gyp

갑자기 무슨 사이클을 돈다는 개소리를 하면서 안된다. 구글에서 Cycles in .gyp file dependency graph detected 라는 문장으로다시 검색.

http://stackoverflow.com/questions/2925094/how-to-build-google-breakpad 를 보니 –no-circular-check 옵션을 붙이면 된단다. 옵션을 붙였더니 그제서야 비주얼스튜디오 솔루션 파일이 생성되었다.

아이고 힘들다…

GCC 최적화 옵션

GCC로 컴파일하던 중 spdlog 라이브러리에서 컴파일시 -O3 옵션을 사용하는 것을 보고 궁금증이 생겨 찾아보았다.

GCC 최적화 옵션에 대해 자세하게 설명되어 있는 페이지.

http://jinynet9.tistory.com/113

* 커널 컴파일 시 최적화 옵션 -O2만 사용하는 이유
커널은 인라인 함수를 많이 사용하고 있다. -O3 최적화는 컴파일러가 판단해서 인라인을 인라인이 빠른 것은 인라인으로, 함수가 빠른 것은 함수로 바꿔버린다. 커널은 최적화된 수행 속도를 위해 의도적으로 인라인 함수를 사용하고 있어서 컴파일러에 의해서 자의적으로 함수로 바뀌는 것을 막기 위해 -O2 옵션을 사용한다.

커널 컴파일은 아니지만 최적화 옵션을 -O2 로 변경했다. 컴파일 옵션을 변경하고 -O3일 때와 파일 크기를 비교해보았는데 거의 차이가 나지 않았다. 앞으로도 -O2로 사용하면 될듯하다.

std::thread 사용법

간단히 스레드를 만들어 테스트 해야할 일이 있어 std::thread를 찾아보고 만들어봤다.

예전에는 boost::thread를 이용했었는데 C++11에 오면서 아예 다 내장되었다는게 놀랍고 신기하다.

#include <iostream>
#include <thread>
#include <windows.h>

char* target_msg = "test";
char msg[1024] = {0,};

void callback_function(int thread_num)
{
    while(true)
    {
        strcpy_s(msg, target_msg);
        //std::cout << "copy (" << thread_num << ")" << std::endl;
        Sleep(10);
    }
}

int main(void)
{
    std::thread thread1(callback_function, 1);
    std::thread thread2(callback_function, 2);

    thread1.join();
    thread2.join();

    return 0;
}

윈도우에서 C++ Boost 사용하기

윈도우에서 C++ 작업시 유용한 Boost 라이브러리를 사용하기 위해서는 빌드를 해야한다. 파일시스템 등을 다루는 등의 운영체제에 의존하는 기능들을 사용하기 위해 빌드해야한다고 한다.

  1. http://www.boost.org 에 들어가서 Boost를 다운 받는다.
  2. 압축을 풀고 디렉토리에 들어가 bootstrap.bat 를 실행한다.
  3. b2 –help 를 실행해서 한번 도움말을 쭉 읽어본다.
  4. 윈도우 커맨드창을 열고 해당 다음의 명령을 입력하여 빌드를 시작한다. 64비트, 디버그/릴리즈 모두, 멀티쓰레드, MPI 사용 안함으로 빌드한다.
  5. b2 variant=debug,release link=static,shared threading=multi address-model=64 –without-mpi -j8 stage
  6. 빌드 옵션은 여러가지가 더 있다. 찾아봐서 자기가 필요한대로 설정한다.
  7. -j8은 몇개의 작업을 동시에 하는지를 결정한다. 4코어인 경우에는 -j4를 해주면 모든 코어를 다 사용하게 된다. 적당하게 설정하는 것이 좋다.

빌드에는 시간이 꽤 걸린다.

다음의 링크를 참조했다.

C#에서 HTTP POST로 JSON 데이터 보내는 방법

회사 업무 중 HTTP POST로 Request Body에 JSON을 넣어서 보내야 할 일이 있어서 간단하게 짜본 WinForm 프로그램이다.

이런 코드들을 간단하면서도 막상 필요할 때 찾아서 쓰기가 귀찮아서 찾아보기 쉽게 여기에 적어둔다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:40080/Default.aspx?cmd=2");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{"kakao_id":"1","image_url":"http://teste11111.com","public_profile":"Y"}";

streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();

var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
MessageBox.Show(result);
}
}
}
}
}

 

리눅스에서 boost 라이브러리 빌드하기

부스트 라이브러리를 리눅스에서 사용하기 위한 절차를 기록해본다.

내 서버의 경우는 CentOS 6.4 버전이며 yum을 이용해 최신의 업데이트가 모두 다 되어있는 상태다.

일단 boost.org에서 최신 소스를 받는다. 이 글을 쓰고 있는 2013년 10월 14일 기준으로 1.54 버전이 가장 최신이다. unix용으로는  tar.gz과 tar.bz2 형식으로 제공되고 있는데 아무래도 압축효율이 높은 bz2 파일을 다운 받았다.

적당한 디렉토리에 받은 파일을 놓고 bunzip2 명령을 이용해 압축을 해제하면 tar 파일이 나온다. tar xvf boost_1_54_0.tar 명령을 이용해서 압축을 해제한다.

압축을 해제한 디렉토리로 들어가서 ./bootstrap.sh 파일을 실행한다.

[root@83rpm boost_1_54_0]# ./bootstrap.sh
Building Boost.Build engine with toolset gcc... tools/build/v2/engine/bin.linuxx86_64/b2
Detecting Python version... 2.6
Detecting Python root... /usr
Unicode/ICU support for Boost.Regex?... not found.
Backing up existing Boost.Build configuration in project-config.jam.1
Generating Boost.Build configuration in project-config.jam...
Bootstrapping is done. To build, run:
./b2
To adjust configuration, edit 'project-config.jam'.
Further information:
- Command line help:
./b2 --help
- Getting started guide:
http://www.boost.org/more/getting_started/unix-variants.html
- Boost.Build documentation:
http://www.boost.org/boost-build2/doc/html/index.html
[root@83rpm boost_1_54_0]#

위와 같은 메시지가 나타난다.

메시지에 나타난대로 ./b2 명령어를 입력하면 빌드가 시작된다. 내 서버의 CPU는 Xeon E3 1220 인데도… 꽤나 오래걸린다. 빌드하는 동안 CPU 사용률이 30~50% 정도를 왔다갔다한다. 대략 10~15분 정도 걸리는 것 같다.

cc.compile.c++ bin.v2/libs/wave/build/gcc-4.4.7/release/link-static/threading-multi/token_ids.o
gcc.compile.c++ bin.v2/libs/wave/build/gcc-4.4.7/release/link-static/threading-multi/wave_config_constant.o
common.mkdir bin.v2/libs/wave/build/gcc-4.4.7/release/link-static/threading-multi/cpplexer
common.mkdir bin.v2/libs/wave/build/gcc-4.4.7/release/link-static/threading-multi/cpplexer/re2clex
gcc.compile.c++ bin.v2/libs/wave/build/gcc-4.4.7/release/link-static/threading-multi/cpplexer/re2clex/aq.o
gcc.compile.c++ bin.v2/libs/wave/build/gcc-4.4.7/release/link-static/threading-multi/cpplexer/re2clex/cpp_re.o
gcc.archive bin.v2/libs/wave/build/gcc-4.4.7/release/link-static/threading-multi/libboost_wave.a
common.copy stage/lib/libboost_wave.a
...updated 1084 targets...
The Boost C++ Libraries were successfully built!
The following directory should be added to compiler include paths:
/backup/program/boost_1_54_0
The following directory should be added to linker library paths:
/backup/program/boost_1_54_0/stage/lib
[root@83rpm boost_1_54_0]#

한참 기다리면 위와 같은 메시지가 나온다. 부스트 라이브러리 빌드에 성공했다는 메시지와 컴파일러에서 인클루드할 경로, 라이브러리 경로를 알려주는 메시지이다.

이것으로 끝.

윈도우에서 빌드할 때는 여러가지 옵션을 넣고 한 것 같은데 리눅스에서는 너무 쉽게 끝나서 뭔가 이상하다. 혹시나 이 빌드 방법이 잘못되었다면 다음번에 수정해 나가도록 한다.

C#에서 엔디안 변경

C#에서 네트워크 통신을 할게 있어서 바이트오더를 빅엔디안으로 해주려다가 알게 된게 있어서 정리한다.

일단 바이트오더링을 하기 위해 리틀엔디안-빅엔디안의 변환이 필요한데 C#에는 이를 지원하는 메서드가 이미 있었다.

http://msdn.microsoft.com/en-us/library/fw3e4a0f 에 있는 HostToNetworkOrder 와 NetworkToHostOrder 라는 메서드인데 이상한건 이 메서드들이 int16, int32, int64만 지원한다는 것이다. 난 uint16, uint32를 변경해야했기에 아무리 해봐도 이 메서드를 통해서는 바이트오더를 변경할 수 없었다. 강제로 형변환도 해봤지만 데이터가 잘못 들어가기만 했다.

구글을 한참 뒤져서 스택오버플로우에서 답을 찾았다.

http://stackoverflow.com/questions/11232594/c-sharp-reversed-ushort

위 링크의 리플처럼 다음의 코드를 사용하면 된다.

var arr = new byte[1];

arr = BitConverter.GetBytes(total_length);
Array.Reverse(arr);
arr.CopyTo(buffer, offset);
offset += Marshal.SizeOf(total_length);

원리는 바이트배열을 선언하고 비트컨버터를 통해 바이트를 구한다음 Array.Reverse()를 통해 바이트를 거꾸로 하는 것이다. 한마디로 바이트오더링을 직접 구현한 것이라고 보면 될 것 같다.

여튼 이 코드를 통해 테스트해보니 정상작동함을 확인했다.

Boost alt_sstream_impl.hpp warning C4819 에러 해결 방법

열심히 작업하고 빌드를 하는데 계속 warning 메시지가 떴다.

내용은

1>C:Libraryboost_1_51_0boost/format/alt_sstream_impl.hpp : warning C4819: 현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다. 데이터가 손실되지 않게 하려면 해당 파일을 유니코드 형식으로 저장하십시오. (..srcbusinessservicepbbmcacheMemberInfoManager.cpp)

빌드가 안되는 것도 아니고 프로그램에 오류가 있는 것도 아니지만 뭔가해서 이 메시지를 찾아보았다.

저 메시지를 더블클릭하면 부스트의 alt_sstream_impl.hpp 파일이 열리면서 파일 인코딩에 문제가 있다고 팝업창이 뜬다. 이 파일을 열고 한참 봤지만 문제가 없어보인다. 그냥 인코딩변환해버리면 저 에러메시지가 사라지겠지만 부스트 파일을 건드리는건 여간 기분이 찜찜한지라 구글에서 검색시작.

StackOverflow에서 다음의 글을 찾았다.

http://stackoverflow.com/questions/10501634/warning-c4819-how-to-find-the-character-that-has-to-be-saved-in-unicode

글 내용을 읽어보니 alt_sstream_impl.hpp 파일에 176번 라인의 주석이 문제였다. 에휴…

해결방법은 Notepad++로 이 파일을 열고 176번 라인의 주석을 모두 지워버리고 다시 빌드해보면 위 오류 메시지가 없어진다.

C#에서 엑셀 문서 저장하기

ClosedXML_small2C#으로 사내용으로 쓸 프로그램을 만들다가 엑셀 파일로 저장해야할 일이 생겼다.

인터넷을 찾아헤메다가 결국은 내가 사용하게 된 방법에 대해 정리한다.

찾아본 끝에 내린 결로은 OpenXML 기술을 이용하는 방식으로 택했다. .xlsx라는 가장 최신의 엑셀 포맷이고 MS오피스 뿐만 아니라 오픈오피스에서도 잘 지원한다. OpenXML이 무엇인가에 대해서는 구체적으로 나도 잘 모르겠다. 혹시 관심 있는 사람들은 위키 같은 곳을 찾아봄이 좋을듯하다. 난 엑셀 파일 읽고 쓰기가 필요한 것이지 엑셀 포맷 그 자체에는 별로 관심도 없거니와 알 필요성도 적어서(물론 알면 좋겠지만) 일단은 OpenXML에 대해 잠깐만 웹서핑을 해본 후 사용하기로 결정했다. OpenXML에 대해 더 알고 싶다면 다음의 페이지를 방문해보자.

OpenXML을 사용하기 위해서 ClosedXML 이라는 라이브러리를 이용할 것이고 http://closedxml.codeplex.com 를 참조하면 된다.

내 환경은 Visual Studio 2012 이며 C# Winform .NET 3.5 였는데 이 기능을 이용하기 위해서는 .NET 4.0 으로 프로젝트 설정을 변경해야했다. 4.0 아래 버전에서는 호환이 안되기 때문에 오류가 난다.

다운로드 받은 후 압축을 풀어보면 몇개의 DLL파일과 XML 파일 등으로 이루어져 있으며 C#을 사용했던 사람이라면 별로 어려움 없이 사용할 수 있으리라 본다.

예제코드는 http://closedxml.codeplex.com/wikipage?title=Showcase&referringTitle=Home 에 설명되어 있고 이것을 참조하면서 만들면 별 무리가 없다.

엑셀 파일을 작성하는데 필요한 기초적인 기능은 충분히 제공된다. 결과적으로는 제대로 선택한 것 같고 별 어려움 없이 엑셀 문서를 작성할 수 있었다.

하나 주의할 사항이라면,

엑셀 파일로 작성할 내용이 많아지면 속도가 꽤나 느려질 수 있다. 특히 다수의 셀에 색상을 입힌다거나 Style 속성을 바꾸는 작업 등은 속도를 굉장히 느려지게 할 수 있으니 주의해야한다. 다수의 셀에 특정 Style을 적용하고 싶다면 for 루프를 돌면서 각 셀마다 Style을 지정하지 말고

ws.Range("B" + index.ToString() + ":D" + index.ToString()).Style.Font.Bold = true;
ws.Range("B" + index.ToString() + ":D" + index.ToString()).Style.Font.FontColor = XLColor.White;
ws.Range("B" + index.ToString() + ":D" + index.ToString()).Style.Fill.BackgroundColor = XLColor.Black;

와 같은 코드를 사용해서 한번에 잡아주는 것이 속도 향상에 도움이 된다.

예제페이지처럼 RangeTable을 잡고 한번에 적용해주면 더 속도향상이 되리라 생각하지만 이렇게 하기에는 너무 귀찮아져서 일단은 난 행단위로 처리했다.

(이 ClosedXML 라이브러리를 이용했다면 프로그램 배포시 ClosedXML.DLL 파일도 같이 배포해야하니 이것 역시 주의하자.))

개발이 모두 끝나고서 알게된 것이지만 ClosedXML은 .NET 4.0용과 .NET 3.5용이 있었다. 이런 젠쟝… ( http://closedxml.codeplex.com/releases/view/96561 )