cef3 js和C++交互
来源:互联网 发布:淘宝代购点 编辑:程序博客网 时间:2024/06/04 18:16
参考出处:https://github.com/fanfeilong/cefutil/blob/master/doc/CEF_JavaScript_Cpp.md
JavaScript和Cpp交互示例(Custom Implementation),交互分为js函数中带有callback和没有callback的实例
一个CEF应用程序也可以提供自己的异步JavaScript绑定。
此处演示(js在html中使用,render进程中):
JavaScript注册函数给Render进程,Render进程保存该JavaScript函数
Render进程发消息通知Browser进程
Browser进程处理后,回发消息给Render进程
Render进程调用之前保存的JavaScript函数
步骤:
1、首先在CefRenderProcessHandler的子类里覆写虚方法OnWebKitInitialized,并在该方法的实现里注册一个C++方法给JavaScript(js调用C++方法,render进程使用)
//假设CefRenderProcessHandler的子类为CefRenderProcessHandlerImplvoid CefRenderProcessHandlerImpl::OnWebKitInitialized(){ std::string app_code = //----------------------------------- //声明JavaScript里要调用的Cpp方法 "var app;" "if (!app)" " app = {};" "(function() {" // Send message ,不是回调函数实例 " app.sendMessage = function(name, arguments) {" " native function sendMessage();" " return sendMessage(name, arguments);" " };" // Registered Javascript Function, which will be called by Cpp,有回调函数示例 " app.registerJavascriptFunction = function(name,callback) {" " native function registerJavascriptFunction();" " return registerJavascriptFunction(name,callback);" " };" "})();"; //------------------------------------ // Register app extension module // JavaScript里调用app.registerJavascriptFunction时,就会去通过CefRegisterExtension注册的CefV8Handler列表里查找 // 找到"v8/app"对应的CefV8HandlerImpl,就调用它的Execute方法 // 假设m_v8Handler是CefRenderProcessHandlerImpl的一个成员变量 m_v8Handler = new CefV8HandlerImpl(); CefRegisterExtension("v8/app", app_code,m_v8Handler);}
2、在CefV8Handler的子类的Execute方法里实现sendMessage和registerJavascriptFunction,js执行C++函数时,便是调用此处对应的方法。
// in CefV8HandlerImpl.hclass CefV8HandlerImpl : publice CefV8Handler{public: CefV8HandlerImpl(); ~CefV8HandlerImpl();public: /** * CefV8Handler Methods, Which will be called when the V8 extension * is called in the Javascript environment */ virtual bool Execute(const CefString& name ,CefRefPtr<CefV8Value> object ,const CefV8ValueList& arguments ,CefRefPtr<CefV8Value>& retval ,CefString& exception);private: // Map of message callbacks.typedef std::map<std::pair<std::string, int>, std::pair<CefRefPtr<CefV8Context>, CefRefPtr<CefV8Value> > > CallbackMap;CallbackMap callback_map_;//成员变量,便于js函数中设置有callback时进行调用}CefV8HandlerImpl::CefV8HandlerImpl(){}CefV8HandlerImpl::~CefV8HandlerImpl(){ // Remove any JavaScript callbacks registered for the context that has been released. if (!callback_map_.empty()) { CallbackMap::iterator it = callback_map_.begin(); for (; it != callback_map_.end();) { if (it->second.first->IsSame(context)) callback_map_.erase(it++); else ++it; } }}// in CefV8HandlerImpl.cppbool CefV8HandlerImpl::Execute(const CefString& name //JavaScript调用的C++方法名字 ,CefRefPtr<CefV8Value> object //JavaScript调用者对象 ,const CefV8ValueList& arguments //JavaScript传递的参数 ,CefRefPtr<CefV8Value>& retval //需要返回给JavaScript的值设置给这个对象 ,CefString& exception) //通知异常信息给JavaScript{ // In the CefV8Handler::Execute implementation for “registerJavascriptFunction”. bool handle=false; if(name=="registerJavascriptFunction"){ //保存JavaScript设置的回答函数,使得render进程持有这个callback函数 //以便js执行带有这个callback为参数的函数后,能够执行这个callback,详见步骤3 if (arguments.size() == 2 && arguments[0]->IsString() && arguments[1]->IsFunction()) { std::string message_name = arguments[0]->GetStringValue(); CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext(); int browser_id = context->GetBrowser()->GetIdentifier(); //message_name和browser_id是用于区分当js回调发生时,执行的是哪个js函数的回调 callback_map_.insert( std::make_pair(std::make_pair(message_name, browser_id), std::make_pair(context, arguments[1]))); handle = true; // 此时可以发送一个信息给Browser进程,见第4个步骤 //registerJavascriptFunction有一个callback函数, //因此render进程需要持有这个callback } if(name=="sendMessage"){ //js调用sendMessage之后,c++处理SendMessage,这个没有回调函数, //Execute函数return true,此次交互便结束。 handle = true; } // 如果没有处理,则发异常信息给js if(!handle){ exception="not implement function"; } return true;}
3、在HTML的JavaScript里,通过上面注册的方法向Render进程注册一个回调函数。
// In JavaScript register the callback function.app.setMessageCallback('binding_test', function(name, args) { document.getElementById('result').value = "Response: "+args[0];});// function(name, args)为一个callback,args[0]//消息名为binding_test,
(以下为有回调函数才有的步骤)
4、 Render进程发送异步进程间通信到Browser进程。
5、 Browser进程接收到进程间消息,并处理。
6、 Browser进程处理完毕后,发送一个异步进程间消息给Render进程,返回结果。
7、 Render进程接收到进程间消息,则调用最开始保存的JavaScript注册的回调函数处理之。(将render进程持有的这个registerJavascriptFunction的callback函数执行)
// Execute the registered JavaScript callback if any.if (!callback_map_.empty()) { const CefString& message_name = message->GetName(); CallbackMap::const_iterator it = callback_map_.find( std::make_pair(message_name.ToString(), browser->GetIdentifier()));//根据消息名和浏览器id找到对应的回调函数进行执行,//message_name为binding_test时则执行js的callback,it不是空 if (it != callback_map_.end()) { // Keep a local reference to the objects. The callback may remove itself // from the callback map. CefRefPtr<CefV8Context> context = it->second.first; CefRefPtr<CefV8Value> callback = it->second.second; // Enter the context. context->Enter(); CefV8ValueList arguments; // First argument is the message name. arguments.push_back(CefV8Value::CreateString(message_name)); // Second argument is the list of message arguments. CefRefPtr<CefListValue> list = message->GetArgumentList(); CefRefPtr<CefV8Value> args = CefV8Value::CreateArray(list->GetSize()); SetList(list, args); // Helper function to convert CefListValue to CefV8Value. arguments.push_back(args); // Execute the callback. CefRefPtr<CefV8Value> retval = callback->ExecuteFunction(NULL, arguments); if (retval.get()) { if (retval->IsBool()) handled = retval->GetBoolValue(); } // Exit the context. context->Exit(); }}
8、在CefRenderProcessHandlerImpl::OnContextReleased()里释放JavaScript注册的回调函数以及其他V8资源。
void CefRenderProcessHandlerImpl::OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) { if(m_v8Handler->Get()){ m_v8Handler->Release(); }}
- cef3 js和C++交互
- CEF3和本地程序交互机制
- CEF3和本地程序交互机制
- CEF3开发者系列之JS与C++交互之二
- CEF3开发者系列之JS与C++交互之一
- CEF3开发者系列之JS与C++交互之二
- CEF3开发者系列之JS与C++交互之二
- CEF3之js与c++交互问题解决资料
- Objective-C和JS交互
- iOS webView js和Objective c交互
- CEF3开发者系列之外篇——IE中JS与C++交互
- CEF3开发者系列之外篇——IE中JS与C++交互
- svg和js交互
- WebView和js交互
- JS 和IOS交互
- Android和JS交互
- UIWebView和js交互
- WebView和js交互
- CSS3(一)
- 用C/C++实现的结构化数据处理 二进制文件
- 用类描述计算机中的CPU的速度和磁盘的容量
- 洛谷p1018
- CSS3(二)
- cef3 js和C++交互
- linux下的进程
- 欢迎使用CSDN-markdown编辑器
- Hibernate框架快速入门
- 消息摘要算法MAC实现与应用
- Qt在CPP文件中使用 Q_OBJECT宏
- CSS3(三)
- 大数据正式21
- LINUX C++ 按修改时间清理过期文件函数实现