将std::string转换为v8::string,反之亦然? 我试图在C++中创建我的第一个节点模块。我只想做一个简单的Hello,将我的名字作为参数传递。我找到了将参数转换为v8::strings的方法,这看起来很难看: Local<String> name = String::NewFromUtf8(isolate, *v8::String::Utf8Value(args[0]->ToString())); Local name=String::NewFromUtf8(隔离,*v8::String::Utf8Value(args[0]->ToString());

将std::string转换为v8::string,反之亦然? 我试图在C++中创建我的第一个节点模块。我只想做一个简单的Hello,将我的名字作为参数传递。我找到了将参数转换为v8::strings的方法,这看起来很难看: Local<String> name = String::NewFromUtf8(isolate, *v8::String::Utf8Value(args[0]->ToString())); Local name=String::NewFromUtf8(隔离,*v8::String::Utf8Value(args[0]->ToString());,c++,node.js,string,casting,v8,C++,Node.js,String,Casting,V8,有没有人能给我推荐一个简单的方法来做这种类型的演员?!我错过什么了吗 对于转换为/从std::string,NewFromUtf8和Utf8Value是合适的。但是,对于您的示例,不需要来回转换(事实上,转换效率很低),您只需执行以下操作: Local<String> name = args[0]->ToString(); localname=args[0]->ToString(); 我建议为此创建包装。如果本地句柄不为空,还必须检查它的名称。较新的实现使用MaybeLoca

有没有人能给我推荐一个简单的方法来做这种类型的演员?!我错过什么了吗

对于转换为/从
std::string
NewFromUtf8
Utf8Value
是合适的。但是,对于您的示例,不需要来回转换(事实上,转换效率很低),您只需执行以下操作:

Local<String> name = args[0]->ToString();
localname=args[0]->ToString();

我建议为此创建包装。如果本地句柄不为空,还必须检查它的名称。较新的实现使用MaybeLocal句柄来确保已检查任何结果

我所做的一些例子:

/* Tool: JS execution has been terminated. */
class TerminateEx : public exception {
public:
    virtual const char* what() const throw()
    { return "JSBaseClass: Execution terminated"; };
};

/* Tool: Convert MaybeLocal<> to Local<>
 * Throws TerminateEx if the handle is empty (JS execution has been
 * terminated).
 */
template<typename C>
inline v8::Local<C>
JSBaseClass::toLocalHandle(v8::MaybeLocal<C> handle)
{
    if (handle.IsEmpty())
        throw TerminateEx();
    return handle.ToLocalChecked();
}

/* Tool: Create JS string*/
inline
v8::Local<v8::String>
JSBaseClass::newJSString(v8::Isolate *isolate, const char *str)
{
    return (toLocalHandle(
                v8::String::NewFromUtf8(
                    isolate, str, v8::NewStringType::kNormal)));
};

/* Tool: Create JS string*/
inline
v8::Local<v8::String>
JSBaseClass::newJSString(v8::Isolate *isolate, const string &str)
{
    return newJSString(isolate, str.c_str());
};

/* Tool: Create JS string*/
template<typename T>
inline v8::Local<v8::String>
JSBaseClass::newJSString(const T &info, const string &str)
{
    return newJSString(info.GetIsolate(), str.c_str());
};

[...]

/* Tool: Throw JS exception */
template<typename T> inline void
JSBaseClass::throwJSError(const T &info, const string &text)
{
    info.GetIsolate()->ThrowException(
        v8::Exception::Error(newJSString(info, text.c_str())));
    info.GetReturnValue().SetUndefined();
    return;
};

[...]

/* Tool: Get string from JS value. returns false if the conversion failed. */
inline bool
JSBaseClass::valueToString(
    const v8::Local<v8::Context> &context,
    const v8::Local<v8::Value> &value,
    string *str)
{
    v8::String::Utf8Value utf8Str(
        toLocalHandle(value->ToString(context)));
    if (!*utf8Str)
        return false;

    *str = *utf8Str;
    return true;
}
/*工具:JS执行已终止*/
类TerminateEx:公共异常{
公众:
虚拟常量char*what()常量throw()
{返回“JSBaseClass:执行终止”;};
};
/*工具:将MaybeLocal转换为本地
*如果句柄为空(JS执行已停止),则抛出TerminateEx
*终止)。
*/
模板
内联v8::本地
JSBaseClass::toLocalHandle(v8::Maybellocal句柄)
{
if(handle.IsEmpty())
抛出TerminateEx();
返回句柄。ToLocalChecked();
}
/*工具:创建JS字符串*/
内联
v8::本地
JSBaseClass::newJSString(v8::隔离*隔离,常量字符*str)
{
返回(Tolocahandle)(
v8::String::NewFromUtf8(
分离,str,v8::NewStringType::kNormal));
};
/*工具:创建JS字符串*/
内联
v8::本地
JSBaseClass::newJSString(v8::隔离*隔离、常量字符串和str)
{
返回newJSString(隔离,str.c_str());
};
/*工具:创建JS字符串*/
模板
内联v8::本地
JSBaseClass::newJSString(常量T&info、常量字符串&str)
{
返回newJSString(info.GetIsolate(),str.c_str());
};
[...]
/*工具:抛出JS异常*/
模板内联空
JSBaseClass::throwJSError(常量T和信息、常量字符串和文本)
{
info.GetIsolate()->throweException(
异常::错误(newJSString(info,text.c_str());
info.GetReturnValue().SetUndefined();
返回;
};
[...]
/*工具:从JS值获取字符串。如果转换失败,则返回false*/
内联布尔
JSBaseClass::valueToString(
constv8::本地和上下文,
常量v8::本地值和值,
字符串*str)
{
v8::String::Utf8Value utf8Str(
toLocalHandle(值->ToString(上下文));
如果(!*utf8Str)
返回false;
*str=*utf8Str;
返回true;
}
然后像这样使用它:

try {
    auto isolate = info.GetIsolate();
    auto context = isolate->GetCurrentContext();

    Local<Value> name = JSBaseClass::newJSString(info, "My Name");

    [...]

    string nameStr;

    if (!JSBaseClass::valueToString(context, name, &nameStr)) {
        JSBaseClass::throwJSError(info, "Not a string");
        return;
    }
    [...]
}
catch (JSBaseClass::TemplateEx) {
    return;
}
试试看{
自动隔离=info.GetIsolate();
自动上下文=隔离->GetCurrentContext();
Local name=JSBaseClass::newJSString(信息,“我的名字”);
[...]
字符串名称tr;
if(!JSBaseClass::valueToString(上下文、名称和名称)){
JSBaseClass::throwJSError(信息,“不是字符串”);
返回;
}
[...]
}
catch(JSBaseClass::TemplateEx){
返回;
}

如果您使用较新版本的V8,则应避免使用不推荐的方法。当前的方法大多返回
MaybeLocal
句柄。

您也可以尝试此方法

    void StringConversion(const FunctionCallbackInfo<Value>& args){
        Isolate* isolate = args.GetIsolate(); // isolate will isolate the whole process in new memory space; so that no other thread can make change onto it at the same time 
        v8::String::Utf8Value s(args[0]); // take the string arg and convert it to v8::string
        std::string str(*s); // take the v8::string convert it to c++ class string
        //convert back the **str** to v8::String, so that we can set and return it 
        Local<String> result= String::NewFromUtf8(isolate,str.c_str()); // c_str() will return a pointer to an array that contain null-terminator sequence  
        args.GetReturnValue().Set(result);
    }
void StringConversion(常量函数callbackinfo&args){
Isolate*Isolate=args.GetIsolate();//Isolate将在新的内存空间中隔离整个进程;因此其他线程不能同时对其进行更改
v8::String::Utf8Value s(args[0]);//获取字符串arg并将其转换为v8::String
STD::String STR(*s);//取V8::string转换为C++类字符串
//将**str**转换回v8::String,以便我们可以设置并返回它
Local result=String::NewFromUtf8(隔离,str.c_str());//c_str()将返回指向包含空终止符序列的数组的指针
args.GetReturnValue().Set(结果);
}

谢谢

较新版本的v8还需要:

void Foo(const v8::FunctionCallbackInfo<v8::Value> &args)
{
  // from v8 to cpp
  v8::Isolate* isolate = args.GetIsolate();
  v8::String::Utf8Value str(isolate, args[0]);
  std::string cppStr(*str);

  // back to v8
  v8::Local<v8::String> v8String = v8::String::NewFromUtf8(isolate, cppStr.c_str(), v8::String::kNormalString);
}
void Foo(const v8::FunctionCallbackInfo&args)
{
//从v8到cpp
v8::Isolate*Isolate=args.GetIsolate();
v8::String::Utf8Value str(隔离,参数[0]);
std::字符串cppStr(*str);
//回到v8
v8::Local v8String=v8::String::NewFromUtf8(隔离,cppStr.c_str(),v8::String::kNormalString);
}

好的,我在使用node 12和v8 7.4.288时遇到了很多问题

所有常用的东西都被弃用了,所以我启动了gdb来检查实际的现状

因此-我假设您首先从一个参数中读取字符串-一种合理的方法(我可以从文档和示例中不费吹灰之力地找出的唯一方法)是:

v8::Local<v8::String> fileName; 
fileName = args[0].As<v8::String>();
现在我有足够的空间来存储一些UTF8字符串——我通过调用WriteUtf8函数来实现这一点

(*fileName)->WriteUtf8(isolate, charFileName);
最后,我已经在其他地方(在全局范围内)定义了我的std::string,如下所示

static std::string stringFileName;
所以-要将数据从char*中获取到我的std::string中,我执行以下操作:

stringFileName.assign(charFileName);
如果愿意,还可以通过调用std::string构造函数并在构造函数中向其传递char*,来完成此操作

我删除了我原来的char*以进行清理,因为它不再需要了-当std::string超出范围时,它会在自身之后进行清理-我不知道v8如何在自身之后进行清理,老实说,我不在乎

delete charFileName;
最后,将-v8::String转换为可用的std::String-today(2020年)

另外-如果您现在想在std::string和V8::string之间进行转换,您可能会执行类似的操作-将
std::string
转换为
char*
,创建一个
,取消引用它
(*mylocalv8string)
,并调用
NewFromUtf8(隔离,char*)
在该取消引用的localv8string

节点上>v13
下面是我如何从类型char*转换为类型

v8::本地
2020年fo
delete charFileName;