Chromium web IDL

轉載來自:https://tbolp.github.io/2020/12/04/%E5%9C%A8Chromium%E9%87%8C%E7%9A%84Blink%E4%B8%AD%E6%B7%BB%E5%8A%A0API/?highlight=c

我還沒有實踐成功,只是單純記錄下

參考文檔:

https://github.com/oceanlantern/chrome-blink

https://www.chromium.org/developers/web-idl-interfaces/

https://www.chromium.org/blink/webidl/

在Chromium裏的Blink中添加API

我的目標導出js的接口使得可以在頁面通過js調用C++的一些方法完成任務

前言

關於導出C++接口方法

1 在extension api導出接口方便extension調用

2 在Blink內核中導出接口

我使用方法2完成導出,閱讀一下內容可能需要了解Web IDL,Blink GC,Chromium Task等方面的知識,相關的一些資料在最後給出

環境

chroumium版本 70.0.3538.513

過程

在C++中定義Example類,該類會執行一個耗時操作,完成後調用回調將結果返回

在js裏需要構造Example類,添加一個回調函數,然後調用將結果輸出

添加目錄

在third_party/blink/renderer/modules添加example目錄,idl及對應的C++的實現統一放在這個目錄

編寫IDL文件

1 WebIDL是一種接口描述規範,可以用來生成一些C++和js之間的轉換代碼

2 inishedCallback爲回調限制的類型,編譯時會自動生成一個C++對象V8FinishedCallback與之對應

3 [Constructor]表明該interface可以再js中使用new構造,該屬性可以有參數,對應的C++方法爲static Example* Create(),Example實例被blink GC管理不需要對應的delete

4 Example需要編寫blink::Example與之對應

1
2
3
4
5
6
7
8
callback FinishedCallback = void(DOMString msg);

[Constructor]
interface Example {
boolean Start();
DOMString Name();
void OnFinish(FinishedCallback callback);
};

編寫C++代碼

1 繼承ScriptWrappable類可以提供類型描述,並且該類繼承GarbageCollectedFinalized,所以Example是一個blink GC對象.類Example聲明的方法與idl是對應的,除了構造函數比較特別以外.

2 #include “third_party/blink/renderer/bindings/modules/v8/v8_finished_callback.h”這個文件是根據idl裏面callback自動生成的文件,編譯後纔會有.

3 不要再別的線程裏調用js註冊的回調函數

以上說明在代碼註釋裏面也有對應

example.h

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
#ifndef __EXAMPLE_H__
#define __EXAMPLE_H__
#include <thread>
#include "base/task/post_task.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_finished_callback.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"

// 類Example需要放在blink空間裏
namespace blink {

// 類需要繼承ScriptWrappable提供類型信息
// ScriptWrappable是一個blink GC管理的類不可以直接delete
class Example final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();

public:
// js調用new時調用該函數,相當於對外導出的構造函數
static Example* Create() { return new Example; }
bool Start() {
return base::PostTaskAndReply(
FROM_HERE, base::BindOnce(&Example::startWork, base::Unretained(this)),
base::BindOnce(&Example::finished, base::Unretained(this)));
}

// String與idl文件中DOMString對應
String Name() { return String("Example"); }

void startWork() { std::this_thread::sleep_for(std::chrono::seconds(10)); }

void finished() {
if (this->callback_) {
// 調用js中的回調
this->callback_->InvokeAndReportException(nullptr,
String("task finished"));
}
}

void OnFinish(V8FinishedCallback* callback) { callback_ = callback; }

// 因爲該類包含需要追蹤的類Member<V8FinishedCallback>,該方法必須實現
void Trace(Visitor* visitor) override {
visitor->Trace(callback_);
ScriptWrappable::Trace(visitor);
}

~Example() override = default;

private:
// 保存js註冊的回調
Member<V8FinishedCallback> callback_;
};

} // namespace blink

#endif

example.cc

1
#include "example.h"

編寫編譯文件

修改的地方比較雜,但是不難理解

1 在third_party/blink/renderer/modules/example裏添加以下文件來說明example模塊編譯的規則

BUILD.gn

1
2
3
4
5
6
7
8
9
10

import("//third_party/blink/renderer/modules/modules.gni")

blink_modules_sources("example") {
sources = [
"example.cc",
"example.h",
]
}

2 在third_party\blink\renderer\modules\BUILD.gn文件的deps變量裏添加以下內容確保example模塊被編譯

1
"//third_party/blink/renderer/modules/example",

3 在third_party\blink\renderer\modules\modules_idl_files.gni文件的modules_idl_files裏的get_path_info傳入參數中添加以下內容確保idl文件被編譯

1
"example/example.idl",

4 在third_party\blink\renderer\bindings\modules\v8\generated.gni文件的generated_modules_callback_function_files變量裏添加以下內容確保idl生成的C++文件被編譯

1
2
"$bindings_modules_v8_output_dir/v8_finished_callback.cc",
"$bindings_modules_v8_output_dir/v8_finished_callback.h",

驗證

chromium編譯成功後在console輸入以下語句成功後會在10秒後彈出消息

1
2
3
example = new Example()
example.OnFinish((msg)=>{alert(msg)})
example.Start()

參考資料

https://heycam.github.io/webidl/#idl-types

https://www.chromium.org/developers/web-idl-interfaces

https://www.chromium.org/blink/webidl#TOC-Style

https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md#GarbageCollected

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章