注册新的V8扩展关联指定的js
扩展像window绑定一样除了为每个框架 加载到上下文之外,一旦加载就不能修改,当一个扩展已经加载并试图在扩展加载中访问DOM就会出现DOM不存在的crash。扩展应该在CefRenderProcessHandler::OnWebKitInitialized()函数中使用CefRegisterExtension函数注册。
看看官方的例子:
void MyRenderProcessHandler::OnWebKitInitialized() {
// Define the extension contents.
std::string extensionCode =
"var test;"
"if (!test)"
" test = {};"
"(function() {"
" test.myfunc = function() {"
" native function myfunc();"
" return myfunc();"
" };"
"})();";
// Create an instance of my CefV8Handler object.
CefRefPtr<CefV8Handler> handler = new MyV8Handler();
// Register the extension.
CefRegisterExtension("v8/test", extensionCode, handler);
}
<script language="JavaScript">
alert(test.myfunc()); // Shows an alert box with "My Value!"
</script>
我们再用自己的例子来验证一下。
可以在上一篇的例子代码中修改。
V8JsHandler.cpp
#include "V8JsHandler.h"
CV8JsHandler::CV8JsHandler(void)
{
}
CV8JsHandler::~CV8JsHandler(void)
{
}
bool CV8JsHandler::Execute(const CefString& funcName,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception)
{
//function add
if (funcName == "add")
{
int32 val2 = arguments[0]->GetIntValue();
int32 val1 = arguments[1]->GetIntValue();
int32 sum = val1 + val2;
retval = CefV8Value::CreateInt(sum);
return true;
}
return false;
}
simple_app.h
#pragma once
#include "include/cef_app.h"
class SimpleApp
: public CefApp
, public CefBrowserProcessHandler
, public CefRenderProcessHandler
{
public:
SimpleApp(void);
virtual ~SimpleApp() OVERRIDE;
public:
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() OVERRIDE;
virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() OVERRIDE;
virtual void OnWebKitInitialized() OVERRIDE;
protected:
IMPLEMENT_REFCOUNTING(SimpleApp);
};
simple_app.cc
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "simple_app.h"
#include <string>
#include "include/cef_browser.h"
#include "include/cef_command_line.h"
#include "include/views/cef_browser_view.h"
#include "include/views/cef_window.h"
#include "include/wrapper/cef_helpers.h"
#include "simple_handler.h"
#include "V8JsHandler.h"
SimpleApp::SimpleApp() {}
SimpleApp::~SimpleApp()
{
}
CefRefPtr<CefBrowserProcessHandler> SimpleApp::GetBrowserProcessHandler()
{
return this;
}
CefRefPtr<CefRenderProcessHandler> SimpleApp::GetRenderProcessHandler()
{
return this;
}
void SimpleApp::OnWebKitInitialized()
{
CEF_REQUIRE_RENDERER_THREAD()
// Define the extension contents.
// std::string extensionCode =
// "var MyMath;"
// "if (!MyMath)"
// " MyMath = {};"
// "(function() {"
// " MyMath.add = function(num1, num2) {"
// " native function add();"
// " return add(num1, num2);"
// " };"
// " MyMath.hellow = 'Hello JS!';"
// "})();";
std::string extensionCode = R"(
var MyMath;
if (!MyMath)
MyMath = {};
(function() {
MyMath.add = function(num1, num2) {
native function add();
return add(num1, num2);
};
MyMath.hellow = 'Hello JS!';
})();
)";
//以上两种方式都可以 R"()"是c++11中新增的多行字符串写法
//native function add(); 这个不能少,可以写成native function add(int, int);
//注意多行字符串中不能出现注释,否则会有问题,比如调用的时候发现undefined问题,或者出现少了;的错误提示
CefRefPtr<CefV8Handler> addHandler = new CV8JsHandler();
// Register the extension.
CefRegisterExtension("v8/test", extensionCode, addHandler); //第一个参数不能为空,否则报错,这个名字可以自定义
}
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<script type="text/javascript" >
function CallMyMathAdd()
{
try{
var result = MyMath.add(10, 20);// C++提供的接口,bind到window对象上
alert("10 + 20 = " + result);
}catch(err){
alert("error message: " + err.message);
}
}
function CallMyMathVar()
{
try{
alert("MyMath.hellow: " + MyMath.hellow);
}catch(err){
alert("error message: " + err.message);
}
}
</script>
</head>
<body style="width:100%;height:100%;background-color:green;">
<p>这是c++与JS交互测试脚本</p>
<div >
<button onclick="CallMyMathAdd();">两个数相加</button>
<button onclick="CallMyMathVar();">MyMath的值</button>
</div>
</body>
</html>
运行结果:

如果少了
native function add();
就会出现异常:
异常的字符串是add is not defined
注意extensionCode的两种写法都可以,R"()"是C++11中新增的多行字符串的写法,要注意的是C++中的js代码中的注释也可能出问题,删掉这些注释就好了。
链接:https://pan.baidu.com/s/1mvYLiLII9j9WKHzriNGDNg
提取码:veky
版权声明:本文为hp_cpp原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。