V8节点GYP通过参考以更改值
我想通过节点GYP使用C ++实现V8函数,该节点是突变函数参数的。
// c++
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::Number;
using v8::String;
using v8::Value;
void Method(const FunctionCallbackInfo<Value>&args) {
Isolate* isolate = args.GetIsolate();
// do something to modify args
// e.g) args[0] = "changed now!"
}
这样我就可以像下面一样使用它。
# js file
const str = 'before';
myCppFunction.doSomething(str);
console.log(str);
// I expect str is now 'changed now!'.
这甚至可能吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
(在这里V8开发人员。)定义“可能”。
更明显的答案是“否”。
conder str = ...
之类的变量是对堆上对象的引用(在这种情况下为字符串)。当您调用方法
时,此引用的副本将作为参数传递。重新分配什么arg [0]
点上的点不会影响str
点,因为它是副本。方法
无法更改str
点。哪个使我们转到另一个答案:如果您让
str
继续指向同一字符串,但修改了该字符串的字符? V8不容易让您这样做,因为JavaScript中的字符串被定义为不可变的,但是如果您尽力而为,C ++将使您几乎修改所需的任何内存。但是,这会带来非常奇怪的后果。它将为该程序“打破JavaScript语义”,因为该字符串将在使用的位置更改 。让我将您的示例扩展一点以解释:由于JavaScript引擎执行了依赖字符串不可变性的各种内部技巧,因此甚至可以使奇怪的是,例如字符串可以用作其他字符串的一部分(所谓的“ cons”或“ cons”或“ rope”字符串),例如
const rope = str +'一些附加文本';
:如果您覆盖str
现在的字符,您会在rope中看到这一点。 /code>也是 - 但前提
长话短说,虽然从技术上讲这是可能的,但我不建议这样做。 (哦,而且,更改堆上的字符串对象的长度将构成内存损坏并导致崩溃。)
显而易见的选择是使用包装对象,类似于如果您想实现某些东西,则如何执行此操作像这样的JavaScript(或Java或Python等)中这样的类似:
(V8 developer here.) Define "possible".
The more obvious answer is "no". A variable like
constr str = ...
is a reference to an object on the heap (this object, in this case, being a string). When you callMethod
, a copy of this reference is passed along as a parameter. Reassigning whatarg[0]
points at would not affect whatstr
points at, because it's a copy. There is no way forMethod
to change whatstr
points at.Which gets us to the other answer: what if you let
str
continue to point at the same string, but modified that string's characters? V8 won't easily let you do that, because strings in JavaScript are defined to be immutable, but if you try hard enough, C++ will let you modify almost any memory you want. However, this would have very weird consequences; it would "break JavaScript semantics" for the program, because that string would change everywhere where it's used. Let me expand your example a bit to explain:Since JavaScript engines perform various internal tricks that rely on string immutability, this could get even weirder, e.g. strings can be used as part of other strings (so called "cons" or "rope" strings), such as
const rope = str + 'some additional text';
: if you overwritestr
's characters now, you'd see that inrope
as well -- but only if you haven't yet performed any operation that causedrope
to get "flattened", at which point it's internally turned into full copy of all characters.Long story short, while this is technically possible, I wouldn't recommend it. (Oh, and also, changing the length of the string object on the heap would constitute memory corruption and result in a crash.)
The obvious alternative is to use a wrapper object, similar to how you would do it if you wanted to implement something like this in pure JavaScript (or Java, or Python, etc):