Почему этот указатель указывает на никуда? - PullRequest
2 голосов
/ 30 июня 2010

Я пытаюсь добавить функциональность в проект v8sharp, и у меня возникают некоторые проблемы (я не очень хорош в C ++ - CLI, поэтому я почти уверен, что проблема заключается скорее в моем недостатке в C ++ - CLI) чем злоупотребление v8.)

v8value.cpp:

v8sharp::V8FunctionWrapper^ V8ValueWrapper::WrapFunction(v8::Handle<v8::Value> value) {

  // Now we use the wrapper to make this safe to use
  // this works
  Console::WriteLine("IsFunction-First: {0}", value->IsFunction());
                // persistent so it doesn't get garbage collected
  v8::Persistent<v8::Value> pval(value);
                // create a function wrapper
  V8FunctionWrapper^ bla = gcnew V8FunctionWrapper(pval);
  return bla;
 }

Который должен принимать v8Handle<v8::Value>, который содержит функцию (так будет всегда из-за того, что вызывает эту функцию) и возвращает красивую оболочку .net, чтобы мы могли использовать ее в моем проекте на C #.

Проблема заключается здесь v8functionwrapper.cpp:

#include "v8functionwrapper.h"
#include "v8value.h";


v8sharp::V8FunctionWrapper::V8FunctionWrapper(v8::Persistent<v8::Value> value)
{
    // is this wrong? 
 this->_value = &value;
     // still true
 Console::WriteLine("Constructor: {0}", (*this->_value)->IsFunction());


}

// This function is called by C# and triggers the javascript function
Object^ v8sharp::V8FunctionWrapper::Call([ParamArray]array<Object ^> ^ args)
{
 // Get a refence to the function
 Console::WriteLine("Cast 2");
    // MEMORY VIOLATION: the _value no longer points to a valid object :(
 Console::WriteLine("IsFunction: {0}", (*this->_value)->IsFunction());
 Console::ReadLine();
-- snip --

}

v8functionwrapper.h:

#pragma once
#include "v8.h"

using namespace System;
using namespace System::Reflection;

namespace v8sharp {
public ref class V8FunctionWrapper 
{
public:
 delegate bool V8FunctionCallback(array<Object ^> ^ args);
 Object^ v8sharp::V8FunctionWrapper::Call([ParamArray]array<Object ^> ^ args);
 v8::Persistent<v8::Value> Unwrap();
 V8FunctionWrapper(v8::Persistent<v8::Value> value);
 ~V8FunctionWrapper();
 !V8FunctionWrapper();

private:
 V8FunctionCallback^ _callback;
 v8::v8<Persistent::Value>* _value;

};
}

Из этой строки видно (код отладки): Console::WriteLine("IsFunction: {0}", (*this->_value)->IsFunction()); Указатель _value больше не действителен и вызывает исключение. Почему мой указатель делает недействительным? Это потому, что я указываю на аргумент в конструкторе, и он удаляется? Если так, как я могу получить указатель на него, который не исчезнет. Имейте в виду, что это класс .net, поэтому я не могу смешивать и сопоставлять нативные типы в нем.

1 Ответ

1 голос
/ 30 июня 2010

Вам необходимо создать новое значение v8 :: Persistent в качестве члена вашего класса, поскольку передаваемое вами значение создается в стеке и будет уничтожено, как только WrapFunction вернется. Также не забудьте удалить _value, когда ваш объект уничтожен.

v8sharp::V8FunctionWrapper::V8FunctionWrapper(v8::Persistent<v8::Value> value)
{
    this->_value = new v8::Persistent<v8::Value>(value)
}
...