Android上的V8。 ndk-build抛出"错误:' v8 :: HandleScope :: HandleScope()'受到保护"

时间:2014-11-20 06:33:31

标签: android android-ndk v8

我目前正在关注教程http://lorinbeer.github.io/tutorial/2013/04/19/vatedroid-p2-linking-v8.html。一系列博客文章对我在Android应用程序上运行V8非常有用。我成功编译了V8库而没有错误。但是,我无法使用以下错误运行ndk-build命令:

handk@handk-ubuntu:~/devel/androidWorkspace/vatedroid-tutorial$ ndk-build
[armeabi] Compile++ thumb: vatedroid <= vatedroid.cpp
jni/../include/v8.h: In function '_jstring* Java_com_vatedroid_VateDroidActivity_feedVatedroid(JNIEnv*, jobject, jstring, jstring)':
jni/../include/v8.h:832:13: error: 'v8::HandleScope::HandleScope()' is protected
jni/vatedroid.cpp:26:17: error: within this context
jni/vatedroid.cpp:28:48: error: no matching function for call to 'v8::Context::Scope::Scope(v8::Persistent<v8::Context>&)'
jni/vatedroid.cpp:28:48: note: candidates are:
jni/../include/v8.h:5882:24: note: v8::Context::Scope::Scope(v8::Handle<v8::Context>)
jni/../include/v8.h:5882:24: note:   no known conversion for argument 1 from 'v8::Persistent<v8::Context>' to 'v8::Handle<v8::Context>'
jni/../include/v8.h:5880:9: note: v8::Context::Scope::Scope(const v8::Context::Scope&)
jni/../include/v8.h:5880:9: note:   no known conversion for argument 1 from 'v8::Persistent<v8::Context>' to 'const v8::Context::Scope&'
jni/vatedroid.cpp:32:28: error: 'New' is not a member of 'v8::String'
jni/vatedroid.cpp:33:28: error: 'New' is not a member of 'v8::String'
jni/../include/v8.h: In function 'void Java_com_vatedroid_VateDroidActivity_initVatedroid(JNIEnv*, jobject)':
jni/../include/v8.h:832:13: error: 'v8::HandleScope::HandleScope()' is protected
jni/vatedroid.cpp:69:17: error: within this context
jni/vatedroid.cpp:73:47: error: no matching function for call to 'v8::Context::New(NULL, v8::Local<v8::ObjectTemplate>&)'
jni/vatedroid.cpp:73:47: note: candidate is:
jni/../include/v8.h:5784:25: note: static v8::Local<v8::Context> v8::Context::New(v8::Isolate*, v8::ExtensionConfiguration*, v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::Value>)
jni/../include/v8.h:5784:25: note:   no known conversion for argument 2 from 'v8::Local<v8::ObjectTemplate>' to 'v8::ExtensionConfiguration*'
make: *** [obj/local/armeabi/objs/vatedroid/vatedroid.o] Error 1

我认为 错误:'v8 :: HandleScope :: HandleScope()'受保护 是错误的主要症状,但不知道如何处理因为我不是C / C ++专家。

仅供参考,我把我编译的V8库放在/ libs文件夹中。另外,我复制了最近的V8 git存储库中的所有头文件。我在jni目录中上传文件如下:

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := v8_base
LOCAL_SRC_FILES := ../libs/libv8_base.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := v8_nosnapshot
LOCAL_SRC_FILES :=  ../libs/libv8_nosnapshot.a
include $(PREBUILT_STATIC_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE    := vatedroid
LOCAL_SRC_FILES := vatedroid.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include
LOCAL_LDLIBS    := -llog -landroid
LOCAL_STATIC_LIBRARIES := v8_base v8_nosnapshot
include $(BUILD_SHARED_LIBRARY)

vatedroid.h

#ifndef _VATEDROID_H
#define _VATEDROID_H

#include <jni.h>
#include <v8.h>
#include <android/log.h>

/**
 * execute a script from native
 */
#ifdef __cplusplus
extern "C" {
#endif
    jstring Java_com_vatedroid_VateDroidActivity_feedVatedroid(JNIEnv * env, jobject obj, jstring name, jstring message);
/**
 * initialize the V8 execution environment for vatedroid scripts 
 */
    void Java_com_vatedroid_VateDroidActivity_initVatedroid(JNIEnv * env, jobject obj);
#ifdef __cplusplus
}
#endif
#endif // _VATEDROID_H

vatedroid.cpp

#include "vatedroid.h"
#include <string.h>

v8::Persistent<v8::Context> PrimaryContext;

/**
 *
 */
jstring Java_com_vatedroid_VateDroidActivity_feedVatedroid(JNIEnv * env, jobject obj, jstring name, jstring message) {
    using namespace v8;
    HandleScope scope;
    TryCatch tc;
    Context::Scope context_scope(PrimaryContext);
    jstring retval;
    jboolean isCopy;

    Handle< String > nme = String::New(env->GetStringChars(name, &isCopy));
    Handle< String > cmd = String::New(env->GetStringChars(message, &isCopy));

    Handle< Script > script = Script::Compile(cmd, nme);

    __android_log_write(ANDROID_LOG_DEBUG, "VATEDROID", "Compiled Scipt");

    if (script.IsEmpty()) {
        return env->NewStringUTF("Error: Bottle is empty!");
    }

    __android_log_write(ANDROID_LOG_DEBUG, "VATEDROID", "Feeding Vatedroid");

    Local< Value > result = script->Run();

    if (result.IsEmpty()) {
        __android_log_write(ANDROID_LOG_DEBUG, "VATEDROID", "RESULT IS EMPTY");
        String::Utf8Value error(tc.Exception());
        __android_log_write(ANDROID_LOG_DEBUG, "VATEDROID", *error);
    }
    String::Utf8Value retstr(result);
    retval = env->NewStringUTF(*retstr);
    return retval;
}

/**
 *
 */
 void Java_com_vatedroid_VateDroidActivity_initVatedroid(JNIEnv * env, jobject obj) {
    // log what's happening
    __android_log_write(ANDROID_LOG_DEBUG, "VATEDROID NDK", "INITIALIZING VATEDROID");
    // can be placed at any scope resolution level, this will be redeclared in any V8 aware function 

    using namespace v8;

    // create the scope and context
    // governs local handles
    HandleScope localscope;
    // object template used to create the global object of our context
     Local< ObjectTemplate > global = ObjectTemplate::New();
    // declaration and instantiation of the primary context
    PrimaryContext = Context::New(NULL, global);
}

1 个答案:

答案 0 :(得分:3)

根据您使用的V8 API的版本,您可能会被一个相当重要的API更改所困扰,而这些更改并未得到很好的记录,实际上当前的文档仍然引用了旧的API

在创建上下文时,您应该有v8::Isolate*,它反映了实际的VM实例。创建HandleScope时,必须传入此Isolate对象作为其参数,例如:

v8::HandleScope handle_scope(isolate); 

现在几乎每个V8 API调用都要求您明确传入此隔离。并且,遗憾的是,文档完全没有说明这一点,也没有任何公开构建的V8 Doxygen站点也是最新的。