假设我有本教程中提供的代码.
我如何修改它,以便Point创建的C++对象调用析构函数,并在GC for V8销毁JavaScript包装器时从内存中删除?
我正在使用OpenGL实现重构我的V8并且遇到了执行上下文的问题.
这个概念如下:
V8GL::initialize()
此方法初始化上下文和全局模板.它还使用上下文来表示过剩,因为有几个循环运行,它们也暴露给JS上下文.(例如glut.mainLoop())
V8GL::execute(context, source, url)
此方法主要在给定上下文中执行字符串.我认为必须采用这种方式来隔离使用间隔/超时.
什么行不通:
V8GL::initialize()还附加内置的JavaScript文件并执行它们.这完全没问题.
简化代码:
V8GL::initialize(...) {
v8::Persistent<v8::Context> context = v8::Context::New(NULL, globalTemplate);
v8::Context::Scope context_scope(context);
// cached for glut mainLoop etc.
GlutFactory::context_ = v8::Persistent<v8::Context>::New(context);
execute(context, v8::String::New(...script content...), v8::String::New(...script url path to show for exception stacktraces...);
// after all the stuff was dispatched to the global context, I want to cache the global object for later usage.
v8gl::global = v8::Persistent<v8::Object>::New(context->Global());
context->DetachGlobal();
context.Dispose();
}
V8GL::execute(context, source, filename) {
v8::HandleScope scope;
// Previously, I had …Run Code Online (Sandbox Code Playgroud) 我一直在研究v8源代码,尤其是'mksnapshot'工具如何在v8二进制文件中包含原生javascript文件(runtime.js,json.js ...)的编译图像,并注意到它还包括一个(有点)源的缩小版本.例如,在检查d8可执行文件的内容时,我看到以下代码段:
var $JSON=global.JSON;
function Revive(a,b,c){
var d=a[b];
if((%_IsObject(d))){
if((%_IsArray(d))){
var g=d.length;
Run Code Online (Sandbox Code Playgroud)
在'src/json.js'的开头我看到:
var $JSON = global.JSON;
function Revive(holder, name, reviver) {
var val = holder[name];
if (IS_OBJECT(val)) {
if (IS_ARRAY(val)) {
var length = val.length;
Run Code Online (Sandbox Code Playgroud)
很明显,两个片段都是等效的,但第二个片段在编译过程中转换为第一个片段.
我会理解是否包含原始代码用于检查'toString',但是当我在d8中输入'JSON.stringify'时,我看到的是'function stringify(){[native code]}',那么有什么意义呢?这个?
我下载并构建了JS V8,以便在发布模式下在VS2010中使用.现在我尝试运行Hello World示例:
#include "v8.h"
int _tmain(int argc, _TCHAR* argv[])
{
v8::HandleScope handle_scope;
v8::Persistent<v8::Context> context = v8::Context::New();
v8::Context::Scope context_scope(context);
v8::Handle<v8::String> source = v8::String::New("'Hello' + ', World'");
v8::Handle<v8::Script> script = v8::Script::Compile(source);
v8::Handle<v8::Value> result = script->Run();
context.Dispose();
v8::String::AsciiValue ascii (result);
printf ("%s\n", *ascii);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我添加了附加依赖项:
"C:\v8\build\Release\lib\preparser_lib.lib"
"C:\v8\build\Release\lib\v8_base.lib"
Run Code Online (Sandbox Code Playgroud)
当我尝试编译并运行该程序时,我遇到了一个链接错误:
1>------ Build started: Project: V8_example, Configuration: Release Win32 ------
1>LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
1>v8_base.lib(platform-win32.obj) : error LNK2001: unresolved external symbol …Run Code Online (Sandbox Code Playgroud) Google的v8文档介绍了如何将全局函数添加到JavaScript上下文中.我们可以使用C++ 11中的新lambda特性轻松实现类似printf的函数:
Handle<ObjectTemplate> global = ObjectTemplate::New();
global->Set(String::New("print"), FunctionTemplate::New(
[](const v8::Arguments &args) -> v8::Handle<v8::Value>
{
v8::String::AsciiValue ascii(args[0]);
std::cout << *ascii << "\n";
} ));
Persistent<Context> context = Context::New(NULL, global);
Run Code Online (Sandbox Code Playgroud)
这适用于任何无状态或引用全局C++变量(即std::cout)的全局JavaScript函数.但是,如果我们希望我们的全局JavaScript函数引用非全局C++变量呢?例如,假设我们正在创建几个不同的JavaScript上下文,每个上下文都有自己的print使用不同C++ 的全局函数std::ostream?如果v8函数模板使用的是std::function对象而不是函数指针,我们会这样做:
Persistent<Context> create_context(std::ostream &out)
{
Handle<ObjectTemplate> global = ObjectTemplate::New();
global->Set(String::New("print"), FunctionTemplate::New(
[&out](const v8::Arguments &args) -> v8::Handle<v8::Value>
{
v8::String::AsciiValue ascii(args[0]);
out << *ascii << "\n";
} ));
return Context::New(NULL, global);
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,v8似乎不支持这一点.我假设(希望?)v8有一种方法可以做一些功能相同的东西,但我发现自己被Doxygen神秘化了v8::FunctionTemplate.尝试过类似事情的人是否愿意将这个过程提炼成更容易理解的东西?我还想学习如何创建绑定到C++对象的现有非全局实例的JavaScript对象的全局实例.
我正在尝试创建一些node.js插件.在插件内部,我有一个静态库的调用.一切都编译好,但是当我从javascript调用我的插件函数时,我得到以下内容:
module.js:356
Module._extensions[extension](this, filename);
^
Error: /home/.../Projects/NodeAddonComLibTest/build/Debug/addon.node: undefined symbol: _Z6ctest1Pi
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/home/.../Projects/NodeAddonComLibTest/doTest.js:1:75)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
Run Code Online (Sandbox Code Playgroud)
我的插件代码如下:
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <node.h>
#include <v8.h>
using namespace v8;
using namespace std;
void ctest1(int *);
Handle<Value> setPort(const Arguments& args){
HandleScope scope;
if (args.Length() != 1) {
ThrowException(Exception::TypeError(String::New("Wrong number of arguments.")));
return scope.Close(Undefined());
}
// ========================= …Run Code Online (Sandbox Code Playgroud) 我刚刚将 V8 版本升级到 3.20.16(从一些非常旧的版本)。我不能再使用
Handle<Object> obj /* = ... */;
Persistent<Object> p = Persistent<Object>::New( obj );
Run Code Online (Sandbox Code Playgroud)
创建对象的持久句柄。编译器建议static T* v8::Persistent<T>::New(v8::Isolate*, T*) [with T = v8::Object]改用。但是,如果我将代码更改为
Handle<Object> obj /* = ... */;
Persistent<Object> p = Persistent<Object>::New( Isolate::GetCurrent(), *obj );
Run Code Online (Sandbox Code Playgroud)
编译器抱怨这个函数是私有的。我现在如何Persistent<Object>从正常创建句柄Handle<Object>?
我用谷歌搜索,我发现的唯一一件事是文档似乎相互矛盾:
Persistence<T>::New仍然是要走的路提前感谢您的任何帮助
这是一个node.js插件模块,我用C++编写,使用node-gyp构建.当StoreFunction我试图存储一个指向函数的指针,以便我以后可以使用它
当我稍后尝试在InvokeFunction中调用它时,我得到一个Segmentation错误.如果我检查两个函数中的指针(使用cout)它们是相同的值,那令我困惑的是什么.
所以我猜测调用两个函数之间调用上下文的变化或者我不明白我指向的是什么.
所有(ummmmmm)指针在这里感谢我的问题..............
Run Code Online (Sandbox Code Playgroud)#include <node.h> #include <v8.h> using namespace v8; v8::Persistent<v8::Function> callbackFunction; Handle<Value> StoreFunction(const Arguments& args) { HandleScope scope; callbackFunction = *Local<Function>::Cast(args[0]); return scope.Close(Undefined()); } Handle<Value> InvokeFunction(const Arguments& args) { HandleScope scope; Local<Value> argv[1] = { String::New("Callback from InvokeFunction")}; callbackFunction->Call(Context::GetCurrent()->Global(), 1, argv); return scope.Close(Undefined()); } void init(Handle<Object> target) { NODE_SET_METHOD(target, "StoreFunction", StoreFunction); NODE_SET_METHOD(target, "InvokeFunction", InvokeFunction); } NODE_MODULE(someaddonmodule, init);
当然还有一些叫js ...........
var myaddon = require('../build/Release/someaddonmodule');
myaddon.StoreFunction(function(data){
console.log("Called back: "+data);
});
myaddon.InvokeFunction(); //causes a segmentation fault
Run Code Online (Sandbox Code Playgroud) 我正在使用:https://github.com/Buildstarted/Javascript.ViewEngines作为额外的Viewengine.
这样我可以服务器端渲染javascript,反应,角度,...(它以前工作)
为此,我需要在根目录中包含几个dll(这很奇怪,但总是这样做)
文件是:
ClearScriptV8-64.dll
V8-ia32.dll
在本地运行时(在2台开发计算机上).一切都运行正常.当我发布到Azure或我自己的服务器上的"Web部署"时,问题就开始了.
我自己的发布给了我这个:
无法加载文件或程序集"ClearScriptV8-32"或其依赖项之一.尝试加载格式不正确的程序.
Azure还:无法加载文件或程序集"ClearScriptV8-64"或其依赖项之一.尝试加载格式不正确的程序.
我想用JavaScript引擎独立的,如我将在命令行中运行它解释了V8 在这里:
$> ./v8-shell -e 'print("10*10 = " + 10*10)'
Run Code Online (Sandbox Code Playgroud)
我希望javascript执行一些http请求,最好使用jQuery API,但XMLHttpRequest也可以.
V8中是否有内置方法来执行此操作?如果没有实现访问者/ cpp扩展,有没有办法实现它?
embedded-v8 ×10
v8 ×7
javascript ×4
c++ ×3
node.js ×2
.net ×1
add-on ×1
asp.net ×1
asp.net-mvc ×1
c# ×1
libuv ×1