자바 스크립트로 모든 것을 해결하면 좋겠지만 

시스템에 따라서 필요한 것이 있죠...

이런거 만들때 C 나 C++ 로 만들어야 합니다. 

이런것을 네이트브 애드온이라고 합니다. 

네이티브 애드온은 C++ 프로그램을 공유라이브러리로 만들고 

이를 자바 스크립트에서 바로 이용가능하게 만드는 겁니다. 

이런 것을 만들기 위해서 

우리는 nw-gyp 라는 것을 설치해야 합니다. 

이것은 각 플랫폼별로 빌드를 할 수 있도록 도와 주는 툴인데

여기서는 자세한 설명을 하지 않으려 합니다.

이 강좌는 윈도우가 중심이고 관련된 강좌는 다른 곳을 참조 바랍니다. 

하지만 nw-gyp 을 설치해야 하기 때문에 

다음과 같이 명령창에서 실행합니다.

c:\> npm install -g nw-gyp
다음은 실행 결과 마지막 내용입니다.
C:\Users\frog\AppData\Roaming\npm\nw-gyp -> C:\Users\frog\AppData\Roaming\npm\node
_modules\nw-gyp\bin\nw-gyp.js
nw-gyp@0.10.9 C:\Users\frog\AppData\Roaming\npm\node_modules\nw-gyp
├── which@1.0.5
├── osenv@0.0.3
├── graceful-fs@2.0.1
├── rimraf@2.2.2
├── mkdirp@0.3.5
├── semver@2.1.0
├── nopt@2.1.2 (abbrev@1.0.4)
├── fstream@0.1.24 (inherits@2.0.1)
├── npmlog@0.0.6 (ansi@0.2.1)
├── glob@3.2.7 (inherits@2.0.1)
├── tar@0.1.18 (inherits@2.0.1, block-stream@0.0.7)
├── minimatch@0.2.12 (sigmund@1.0.0, lru-cache@2.3.1)
└── request@2.27.0 (json-stringify-safe@5.0.0, forever-agent@0.5.0, aws-sign@0.
3.0, qs@0.6.5, tunnel-agent@0.3.0, oauth-sign@0.3.0, cookie-jar@0.3.0, mime@1.2.11
, node-uuid@1.4.1, http-signature@0.10.0, hawk@1.0.0, form-data@0.1.2)

c:\>


자 이제 본격적인 네이티브 모듈을 한번 작성하고 사용해 봅니다. 

역시나 윈도우가 되었던 뭐가 되었던 처음 짜는 프로그램 예제로는 "hello world" 죠...

이런 비스므리한 것으로 네이티브 애드온 모듈 작성법을 학습해 봅시다.

이 부분은 실행화면은 굳이 표시하지 않으려 합니다.

별로 의미가 없거든요...

메세지만 딸랑 뜰텐데 그걸 캡쳐 해서 표시하는 것이 더 나을 것 같습니다.

왜냐?

제가 귀찮거든요.. ㅜㅜ

다음과 같은 디렉토리를 일단 만듭니다. 

C:\nw\addon\lib> 

이곳으로 이동합니다. 

다음 두 파일을 만듭니다. 

binding.cc
binding.gyp
----[binding.cc]--------------------------------------------------------------
#include <node.h>
#include <v8.h>

using namespace v8;

Handle<Value> Method(const Arguments& args) {
  HandleScope scope;
  return scope.Close(String::New("world"));
}

void init(Handle<Object> target) {
  NODE_SET_METHOD(target, "hello", Method);
}

NODE_MODULE(binding, init)
--------------------------------------------------------------------------------
----[binding.gyp]--------------------------------------------------------------
{
  'targets': [
{
 'target_name': 'binding',
 'sources': [ 'binding.cc' ]
}
  ]
}
--------------------------------------------------------------------------------
내용은 설명하지 않겠습니다. 

이 강좌는 빌드 과정에 집중합시다. 

다른 강좌에서 이 부분에 대한 설명을 하나씩 할 것 이거든요...

여기서 다음과 같은 명령으로 빌드 환경을 잡습니다. 

nw-gyp configure --target=<버전>

<버전>은 node-webkit 버전을 의미합니다. 

버전은 어떻게 확인할까요?

처음 작성했던 hello world 예제 아시죠?

그걸 실행하면 브라우져 처럼 동작하죠?

URL 창에 다음 같이 칩니다. 

nw:version
그러면 다음과 같이 브라우저에 버전 관련 정보가 뜹니다.

node-webkit v0.8.0-rc1
node.js v0.10.18
Chromium 30.0.1599.66
이 버전 중 우리가 필요한 것은 0.8.0 입니다. 

일단 c:\nw\addon\lib 디렉토리를 이동합니다.

다음과 같이 수행합니다. 

nw-gyp configure --target=0.8.0

다음은 수행 결과 입니다. 

c:\nw\addon\lib>nw-gyp configure --target=0.8.0
gyp info it worked if it ends with ok
gyp info using nw-gyp@0.10.9
gyp info using node@0.10.22 | win32 | ia32
gyp http GET http://node-webkit.s3.amazonaws.com/v0.8.0/nw-headers-v0.8.0.tar.gz
gyp http 200 http://node-webkit.s3.amazonaws.com/v0.8.0/nw-headers-v0.8.0.tar.gz
gyp http GET http://node-webkit.s3.amazonaws.com/v0.8.0/nw.lib
gyp http GET http://node-webkit.s3.amazonaws.com/v0.8.0/nw.lib
gyp http 200 http://node-webkit.s3.amazonaws.com/v0.8.0/nw.lib
gyp http 200 http://node-webkit.s3.amazonaws.com/v0.8.0/nw.lib
gyp info spawn python
gyp info spawn args [ 'C:\\Users\\frog\\AppData\\Roaming\\npm\\node_modules\\nw-
gyp\\gyp\\gyp',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'msvs',
gyp info spawn args   '-G',
gyp info spawn args   'msvs_version=auto',
gyp info spawn args   '-I',
gyp info spawn args   'c:\\nw\\addon\\lib\\build\\config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\Users\\frog\\AppData\\Roaming\\npm\\node_modules\\nw-
gyp\\addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\Users\\frog\\.nw-gyp\\0.8.0\\common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=C:\\Users\\frog\\.nw-gyp\\0.8.0',
gyp info spawn args   '-Dmodule_root_dir=c:\\nw\\addon\\lib',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--generator-output',
gyp info spawn args   'c:\\nw\\addon\\lib\\build',
gyp info spawn args   '-Goutput_dir=.' ]
gyp info ok

잘되는 군요 ^^

그리고 나서 빌드를 수행 합니다. 

nw-gyp build
 
c:\nw\addon\lib> nw-gyp build
gyp info it worked if it ends with ok
gyp info using nw-gyp@0.10.9
gyp info using node@0.10.22 | win32 | ia32
gyp info spawn C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe
gyp info spawn args [ 'build/binding.sln',
gyp info spawn args   '/clp:Verbosity=minimal',
gyp info spawn args   '/nologo',
gyp info spawn args   '/p:Configuration=Release;Platform=Win32' ]
Building the projects in this solution one at a time. To enable parallel build, please add the
"/m" switch.
 binding.cc
c:\users\frog\.nw-gyp\0.8.0\src\node.h(124): warning C4996: 'v8::FunctionTemplate::New': was d
eclared deprecated [c:\nw\addon\lib\build\binding.vcxproj]
 C:\Users\frog\.nw-gyp\0.8.0\deps\v8\include\v8.h(3338) : see declaration of 'v8::Fun
 ctionTemplate::New'
 ..\binding.cc(12) : see reference to function template instantiation 'void node::Set
 Method<v8::Handle<T>>(target_t,const char *,v8::InvocationCallback)' being compiled
 with
 [
 T=v8::Object,
 target_t=v8::Handle<v8::Object>
 ]
C:\Users\frog\.nw-gyp\0.8.0\deps\v8\include\v8.h(258): warning C4506: no definition for inline
function 'v8::Persistent<T> v8::Persistent<T>::New(v8::Handle<T>)' [c:\nw\addon\lib\build\bin
ding.vcxproj]
 with
 [
 T=v8::Object
 ]
Creating library c:\nw\addon\lib\build\Release\binding.lib and object c:\nw\addon\lib\bui
 ld\Release\binding.exp
 Generating code
 Finished generating code
 binding.vcxproj -> c:\nw\addon\lib\build\Release\\binding.node
gyp info ok

c:\nw\addon\lib> 

자 이제 어떤 결과가 되었는가를 확인해 봅시다.

c:\nw\addon\lib>tree
.
|-- binding.cc
|-- binding.gyp
|-- build
|   |-- Release
|   |   |-- binding.exp
|   |   |-- binding.lib
|   |   |-- binding.node
|   |   |-- binding.pdb
|   |   `-- obj
|   |       `-- binding
|   |           |-- CL.read.1.tlog
|   |           |-- CL.write.1.tlog
|   |           |-- binding.lastbuildstate
|   |           |-- binding.obj
|   |           |-- binding.write.1.tlog
|   |           |-- cl.command.1.tlog
|   |           |-- link-cvtres.read.1.tlog
|   |           |-- link-cvtres.write.1.tlog
|   |           |-- link-rc.read.1.tlog
|   |           |-- link-rc.write.1.tlog
|   |           |-- link.command.1.tlog
|   |           |-- link.read.1.tlog
|   |           |-- link.write.1.tlog
|   |           `-- vc110.pdb
|   |-- binding.sln
|   |-- binding.vcxproj
|   |-- binding.vcxproj.filters
|   `-- config.gypi
`-- nw-gyp

4 directories, 25 files

c:\nw\addon\lib>
최종 결과 파일은
c:\nw\addon\lib\build\Release\\binding.node
이놈입니다. 

자 이놈을 수행해 봅시다. 

먼저 이전에 했던 것 처럼 package.json 을 다음과 같이 만듭니다 .

----[package.json]--------------------------------------------------------------
{
  "name": "markdown",
  "main": "index.html",
  "window": {
"toolbar": false
  }
}
--------------------------------------------------------------------------------

다음은 index.html 을 다음가 같이 작성합니다. 

----[index.html]----------------------------------------------------------------
<html>
<head>
<meta http-equiv="content-Type" content="text/html; charset=utf-8" /> 
<title>네이티브 애드온 모듈 사용</title>
<script type="text/javascript" src="js/jquery-2.0.3.min.js"></script>
</head>
<body>
<h1>네이티브 애드온 모듈 사용</h1>
<script type="text/javascript" src="main.js"></script>  
</body>
</html>
--------------------------------------------------------------------------------

이제 모듈을 호출하고 실제 모듈에 포함된 함수를 호출하는 main.js 을 작성합니다. 

----[main.js]-------------------------------------------------------------------
$(function(){

var gui = require('nw.gui');
var win = gui.Window.get();
win.showDevTools();

var assert = require('assert');
var binding = require('./lib/build/Release/binding');
assert.equal('world', binding.hello());
console.log('binding.hello() =', binding.hello());
});
--------------------------------------------------------------------------------

다음은 실행 결과 화면 입니다. 
P001_실행.png

[그림 P001_실행.png]