新增native 模組
如果你需要一些fibjs native 模組所提供功能以外的功能,或者你想為fibjs 貢獻程式碼,那麼這篇文章也許對你有幫助。
編寫idl 文件
idl 是fibjs 中用來定義native 模組和物件方法的描述性語言。
在開始寫自己的fibjs 模組的之前你需要先寫idl 描述性語言。我們以自訂模組name 為例。我需要寫描述性語言name.idl ,把這個檔案放入${{fibjs_project_dir}}/idl/zh-cn/ 目錄下,其中${{fibjs_project_dir}} 代表fibjs 的專案所在目錄。
我們的name 模組很簡單,只有一個test 方法,其參數是一個字串,這個字串是歌詞, test 方法判斷這歌詞對不對,傳回值是boolean 類型。 name.idl 寫如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14/*! @brief name module
how to use
@code
var name = require('name');
@endcode
*/
module name
{
/*! @brief 测试输入的字符串是不是正确的歌词
@param lyrics 歌词
*/
static Boolean test(String lyrics);
};
產生頭檔
在tools 目錄下執行fibjs idlc.js
命令,這會讀取idl 目錄下所有的idl 文件並解析,生成對應的頭文件和文檔,其中生成的頭文件都會存放在"fibjs/include/ifs/"目錄下。例如name.idl 會自動產生${{fibjs_project_dir}}/fibjs/include/ifs/name.h 這個頭文件,其中定義了name_base 這個類別。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76/***************************************************************************
* *
* This file was automatically generated using idlc.js *
* PLEASE DO NOT EDIT!!!! *
* *
***************************************************************************/
#ifndef _name_base_H_
#define _name_base_H_
/**
@author Leo Hoo <lion@9465.net>
*/
#include "../object.h"
namespace fibjs {
class name_base : public object_base {
DECLARE_CLASS(name_base);
public:
// name_base
static result_t test(exlib::string lyrics, bool& retVal);
public:
static void s__new(const v8::FunctionCallbackInfo<v8::Value>& args)
{
CONSTRUCT_INIT();
Isolate* isolate = Isolate::current();
isolate->m_isolate->ThrowException(
isolate->NewString("not a constructor"));
}
public:
static void s_test(const v8::FunctionCallbackInfo<v8::Value>& args);
};
}
namespace fibjs {
inline ClassInfo& name_base::class_info()
{
static ClassData::ClassMethod s_method[] = {
{ "test", s_test, true }
};
static ClassData s_cd = {
"name", true, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, 0, NULL, 0, NULL, NULL, NULL,
&object_base::class_info()
};
static ClassInfo s_ci(s_cd);
return s_ci;
}
inline void name_base::s_test(const v8::FunctionCallbackInfo<v8::Value>& args)
{
bool vr;
METHOD_NAME("name.test");
METHOD_ENTER();
METHOD_OVER(1, 1);
ARG(exlib::string, 0);
hr = test(v0, vr);
METHOD_RETURN();
}
}
#endif
編寫原始碼
方法s_test 是v8 的存取器,它包覆了方法test 。這裡我們只要實作test 方法,test 方法有兩個參數,v0 是輸入的歌詞,vr 是回傳值。我們將cpp 檔案放在${{fibjs_project_dir}}/fibjs/src/ 目錄下, 頭檔放在${{fibjs_project_dir}}/fibjs/include 目錄下。本例不需要額外的頭檔。我們在fibjs/src/ 目錄下新建一個檔案name.cpp 內容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include "object.h"
#include "ifs/name.h"
namespace fibjs
{
DECLARE_MODULE(name);
result_t name_base::test(exlib::string lyrics, bool& retVal)
{
if (lyrics == "youmeiyounameyishougehuirangnituranxiangqiwo")
retVal = true;
else retVal = false;
return 0;
}
}
需要注意的是DECLARE_MODULE(name);
這句話,這句話聲明了"name" 這個module 並把它註冊到javascript 物件上。在編寫原始碼的時候需要加上這句話。在v0.25.0
及以後的版本中,我們將fibjs 的模組剝離了出來以便更好的複用,所以你仍需要在fibjs/program/src/fibjs.cpp
文件中的importModule
函數中添加如下一句話:IMPORT_MODULE(name);
來安裝自定義的模組。
編譯並測試
在windows 上編譯之前,需要先執行一遍fibjs tools/vsmake.js
然後build。編譯運行結果如下:
總結
學會如何增加和修改fibjs 的native 模組和物件。我們可以編寫各種各樣複雜的模組,還可以移植第三方函式庫到fibjs 作為支援來編寫我們的模組。歡迎您來為fibjs 貢獻更多的力量。