libCEF中C++與JavaScript的互動呼叫
前言
前一篇文章介紹過CEF在WIN32程式中嵌入chrome核心瀏覽器的例子:http://blog.csdn.net/mfcing/article/details/43973377
這裡介紹的是嵌入瀏覽器後,網頁的JS指令碼函式與C++程式碼的互動,這個很多地方都用得到。比如:音樂播放器裡網頁上的播放,客戶端資源中心裡的資源下載……
JS呼叫C++函式
首先需要重寫CefRenderProcessHandler的OnContextCreated介面,為什麼呢?學習CEF庫的使用必須仔細閱讀他的標頭檔案裡的注視部分:
這個介面實在chrome的V8引擎建立後呼叫的,在這裡我們需要將JS裡面呼叫的函式和C++的執行函式關聯起來,這樣JS就可以“執行”C++程式碼了。// Called immediately after the V8 context for a frame has been created. To // retrieve the JavaScript 'window' object use the CefV8Context::GetGlobal() // method. V8 handles can only be accessed from the thread on which they are // created. A task runner for posting tasks on the associated thread can be // retrieved via the CefV8Context::GetTaskRunner() method. /// /*--cef()--*/ virtual void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) {}
我們的函式都是定義在window物件中的(不知道JS中這個是不是叫物件),根據注視我們需要GetGlobal獲取這個物件。
我的程式碼是這樣的:
CefRefPtr<CefV8Value> window = context->GetGlobal(); CefRefPtr<CefV8Accessor> myV8Acc = new CCefV8Accessor; CefRefPtr<CefV8Value> val = CefV8Value::CreateString(L"Application"); CefString cefException; myV8Acc->Set(L"name", window, val, cefException); CefRefPtr<CefV8Value> pObjApp = CefV8Value::CreateObject(myV8Acc); window->SetValue(L"Application", pObjApp, V8_PROPERTY_ATTRIBUTE_NONE); CefRefPtr<CefV8Handler> myV8handle = new CCefV8Handler(); CefRefPtr<CefV8Value> myFun = CefV8Value::CreateFunction(L"SetAppState", myV8handle); static_cast<CCefV8Handler*>(myV8handle.get())->AddFun(L"SetAppState", &CChromeJsCallback::JsSetAppState); pObjApp->SetValue(L"SetAppState", myFun, V8_PROPERTY_ATTRIBUTE_NONE); myFun = CefV8Value::CreateFunction(L"OneClickInstall", myV8handle); static_cast<CCefV8Handler*>(myV8handle.get())->AddFun(L"OneClickInstall", &CChromeJsCallback::JsOneKeyInstall); pObjApp->SetValue(L"OneClickInstall", myFun, V8_PROPERTY_ATTRIBUTE_NONE); myFun = CefV8Value::CreateFunction(L"DownLoadFile", myV8handle); static_cast<CCefV8Handler*>(myV8handle.get())->AddFun(L"DownLoadFile", &CChromeJsCallback::JsDownloadFile); pObjApp->SetValue(L"DownLoadFile", myFun, V8_PROPERTY_ATTRIBUTE_NONE);
所有的JS函式都是在window.Application上的,因此需要在window 物件上面建立Application 物件,CefV8Value::CreateObject用來建立物件。CefV8Value這個類在JS處理中至關重要,要必要好好看看標頭檔案裡面的注視,CEF的注視是相當詳細的。
建立函式物件,並將JS函式繫結到C++函式指標上面的過程是重點詳細介紹下
CefRefPtr<CefV8Handler> myV8handle = new CCefV8Handler(); CefRefPtr<CefV8Value> myFun = CefV8Value::CreateFunction(L"SetAppState", myV8handle); static_cast<CCefV8Handler*>(myV8handle.get())->AddFun(L"SetAppState", &CChromeJsCallback::JsSetAppState); pObjApp->SetValue(L"SetAppState", myFun, V8_PROPERTY_ATTRIBUTE_NONE);
AddFun是自己新增的一個函式,用來把一個函式和氣對應的回撥地址儲存到這個V8物件中,因此用了一個成員變數typedef map<CefString, JS_CALLBACK_FUN> FunctionMap,呼叫函式時V8引擎有一個介面Execute,在這裡我們呼叫函式的名稱到map中去查詢,找到了其對應的回撥地址呼叫函式,這就是JS呼叫C++的過程了。
最上面那段程式碼中,我們又添加了三個函式 SetAppState、OneClickInstall、DownLoadFile到window.application物件上面。
C++程式碼中,這三個函式是這樣寫的:
//JS函式,在其他程序中呼叫
static bool JsSetAppState(const CefV8ValueList& argList, CefRefPtr<CefV8Value>& retValue);
static bool JsOneKeyInstall(const CefV8ValueList& argList, CefRefPtr<CefV8Value>& retValue);
static bool JsDownloadFile(const CefV8ValueList& argList, CefRefPtr<CefV8Value>& retValue);
vCefV8ValueList是一個引數列表,看它的定義typedef std::vector<CefRefPtr<CefV8Value> > CefV8ValueList,retValue當然就是函式的返回值了,有的JS需要根據返回值做相應的處理的。
這裡要注意:CEF可以使用單程序和多程序模式,我程式裡使用的是多程序模式,因此V8引擎的執行是在渲染引擎裡的,不要嘗試在這裡直接去對介面進行處理。介面程序和渲染程序是分開的,資料的話用共享記憶體來做,介面更新發訊息來做。
C++呼叫JS函式
C++呼叫JS函式相對簡單多了,因為CEF有介面可以直接使用CefFrame::ExecuteJavaScript,看看註釋:
// Execute a string of JavaScript code in this frame. The |script_url|
// parameter is the URL where the script in question can be found, if any.
// The renderer may request this URL to show the developer the source of the
// error. The |start_line| parameter is the base line number to use for error
// reporting.
///
/*--cef(optional_param=script_url)--*/
virtual void ExecuteJavaScript(const CefString& code,
const CefString& script_url,
int start_line) =0;
首先需要獲取到我們的瀏覽器裡的主框架物件,code是JS函式和傳入引數的字串,URL可以直接忽略。
void CChromeBrowserUI::ExecuteJavascript( const wstring& strCode )
{
if ( m_pWebBrowser.get() )
{
CefRefPtr<CefFrame> frame = m_pWebBrowser->GetMainFrame();
if ( frame.get() )
{
CefString strCode(strCode.c_str()), strUrl(L"");
frame->ExecuteJavaScript(strCode, strUrl, 0);
}
}
}
注意:函式名和引數名需要用單引號分隔。
我的字串格式化部分:
CString strJsCode;
strJsCode.Format(L"setInstallStatus('%s','%s','%d');", lpData->strId.c_str(), strStatus, nPercent);
這樣,C++就可以呼叫JS的函式並傳入對應的引數了。
總結
要想使用CEF,最好還是仔細閱讀標頭檔案裡面的註釋,很詳細。 執行程式相關推薦
libCEF中C++與JavaScript的互動呼叫
前言 前一篇文章介紹過CEF在WIN32程式中嵌入chrome核心瀏覽器的例子:http://blog.csdn.net/mfcing/article/details/43973377 這裡介紹的是嵌入瀏覽器後,網頁的JS指令碼函式與C++程式碼的互動,這個很多地方都用得到
在 Cef 中實現 C++ 與 JavaScript 互動場景分析
此文已由作者鄧佳佳授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗 本文主要介紹 CEF 場景中 C++ 和 JavaScript 互動(以下簡稱 JS Bridge)中的一些重要節點,包括了 C++/JavaScript 的方法註冊、方法呼叫、回撥管理。以下是一些
Flex與JavaScript互動呼叫函式
一、在JavaScript中呼叫Flex方法 在 Flex 應用中,需要在方法列表中新增指定的公用方法,這樣Flex中的方法才能被JS呼叫到。在Flex中需要通過呼叫addCallback()可以把一個方 法新增到此列表中。 addCallback將一個ActionScr
android中Webview與javascript的互動(互相呼叫)
最近做android專案中遇到要在webview中做與js互動相關的東東,涉及到js中呼叫android本地的方法,於是查了資料整理了一下android和js互相呼叫的過程。如下demo,demo的主要實現過程如下:通過載入本地的html檔案(裡面有js指令碼),實現and
iOS 開發 Object-C和JavaScript互動詳解之OC與JS互動在WKWebView中使用
1.OC與JS互動在UIWebView中使用 2. WKWebView的使用詳解 3.OC與JS互動在WKWebView中使用 // // ViewController.m // oc與js互動WKWebView // // Cr
VC與JavaScript互動(三) ———— JS呼叫C++
太監的原因: 時隔兩年,VC與JavaScript互動系列的最後一篇關於JavaScript如何呼叫c++的文章終於出爐了。為什麼會隔了那麼久?因為本來打算太監的,可是看到熱情的網友們的眼神,從期望變成了失望,在我的心裡激起了層層波瀾。兩年後的今天,還是堅持
Flex與JavaScript互動中如何用Flex呼叫JavaScript
本文和大家重點討論一下Flex與JavaScript的互動:Flex呼叫JavaScript或者被JavaScript呼叫,在Flex中呼叫JavaScript最簡單的方法是使用ExternalInterface(),可以使用此API呼叫任意JavaScript,傳遞引數,獲
C++與QML互動2:在QML中呼叫C++特性
版權宣告:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結和本宣告。 本文連結:https:/
C++與Lua互動1: C++呼叫lua
lua作為一門動態語言,可用來當做配置檔案和實現經常變化的業務功能,很方便的實現熱更新。同時lua作為一門膠水語言,配合強大的C++作邏輯支撐,程式效能高、開發效率快,猶如珠簾合璧,所向無敵。C++與lua的互動主要通過lua的虛擬棧實現,本文不打算深入講解其
C#中webbrowser與javascript(js)交互的方法
新建 基本 tool 開發環境 應用 pub click show 還需要 今天在做一個項目的時候需要用c#搞一個webbrowser,然後有些地方還需要與js交互。所以就查了一下資料,發現很多博客提到了但是卻沒有說下具體的操作。所以我就寫一下. 開發環境是Visual
VC與JavaScript互動(四) ———— WebBrowser或CHtmlView中輕鬆遮蔽指令碼錯誤(JavaScript)
1.什麼是javascript指令碼錯誤 1.1 概述 JavaScript指令碼錯誤包含“執行時錯誤”和“語法錯誤”。 1.2 JavaScript“語法錯誤” JavaScript語法錯誤是指當 JavaScript語句違反了 JavaScript指令碼語言
C#通過webbrowser控制元件與javascript互動
1.C#裡呼叫控制元件裡面網頁的js函式 //呼叫JavaScript的messageBox方法,並傳入引數 object[] objects = new object[1]; objects[0] = “C#訪問JavaScript指令碼";
VC與JavaScript互動(二) ———— 呼叫JS函式
這一章,我們來動手實踐VC呼叫JS函式。 我們動手寫一個HTML,其中包含這樣一段JS程式碼: <script type="text/javascript"> function Add(value1, value2) { return
Android:WebView與Javascript互動(相互呼叫引數、傳值)
Android中可以使用WebView載入網頁,同時Android端的java程式碼可以與網頁上的javascript程式碼之間相互呼叫。 效果圖: (一)Android部分: 佈局程式碼: <LinearLayout xmlns:android="http://s
在 Mac Webview 中 Objective-c 與 JS 互動
http://blog.eqoe.cn/posts/mac-webview-js-oc.html 本文為您圖文演示如何在 OC 中註冊或執行 JS 函式,以實現網頁與程式的互動。 1. 首先我們建立一個 XCode 專案; 2. 新增WebView 到ViewContro
unity 中 c# 與 object-c 互動
C/C++可以直接與object-c互動,只需把檔案字尾寫成.mm就行了。c#又可以和C/C++互動,所以嘛。。。c#也就可以和object-c互動了。 1、在unity中 c#呼叫object-c 函式 首先,定義一個新建一個.mm檔案,然後在裡面定義一個C風格介面的函
c/c++中_stdcall與dll動態呼叫
1._stdcall在動態dll呼叫中的注意事項 為了用vc寫的dll能被其它語言的寫的程式使用,即實現跨語言。我們在dll的函式呼叫約定中使用__stdcall . 但當用GetProcAddress呼叫是卻失敗了. 用dumpbin工具檢視匯出的函式名可以看到
MFC的WebBrowser控制元件 C++與JavaScript之間資料互動傳遞
----------------------------------------------------------------------------------------------------------------------------------------
unity中c#與Objective-C相互呼叫
前言 在unity中接入sdk或者定製一些功能時,需要呼叫系統介面。iphone手機實際操作中,也就是Unity與iOS相互呼叫。我們在Unity中使用c#,iOS中使用Objective-C(以下稱為oc)。 下面介紹他們如何相互呼叫。 c# 呼叫
WebView中Java與JavaScript的互動
> 原文首發於微信公眾號:jzman-blog,歡迎關注交流! Android 開發過程中 WebView 的使用比較廣泛,常用來載入網頁,比如使用 WebView 載入新聞頁面、使用 WebView 開啟本應用的連結以及用 WebView 顯示支付資訊頁面等,那麼如何 Android 開發中如何與