将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;