Guide 開髮指南

新增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。編譯運行結果如下: name

總結

學會如何增加和修改fibjs 的native 模組和物件。我們可以編寫各種各樣複雜的模組,還可以移植第三方函式庫到fibjs 作為支援來編寫我們的模組。歡迎您來為fibjs 貢獻更多的力量。