安卓上的 V8。NDK-build抛出"error: 'v8::HandleScope::HandleScope()' is protected"



我目前正在学习教程,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

瓦德罗伊.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);
}

根据您使用的 V8 API 版本,您可能被一个相当重大的 API 更改所困扰,该更改的文档不是很好,事实上,当前的文档仍然引用了旧的 API。

在创建上下文时,应具有反映实际 VM 实例的v8::Isolate*。 当你创建一个HandleScope时,你必须传入这个Isolate对象作为它的参数,例如:

v8::HandleScope handle_scope(isolate); 

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

最新更新