Я занимаюсь разработкой модуля NodeJS, и его размер файла резко увеличивается, однако я понял, что могу разделить свой модуль на два отдельных модуля. Когда это происходит, только нескольким функциям моего второго модуля необходимо использовать внутренние классы C ++ моего первого модуля. Можно ли как-то передать только прототип первого модуля второму?
Пример:
Модуль А:
Имеет класс под названием cModuleA
:
class cModuleA {
//declarations
data* pointer;
}
Модуль Б:
Имеет около 100 функций, но только один из них должен манипулировать data*
указатели. Нужно вернуть cModuleA
объект (поэтому ему нужен прототип cModuleA
или быть в курсе cModuleA
реализация)
Я попытался экспортировать символы из первого модуля (dllimport/dllexport
в Windows), но мне было просто интересно, есть ли лучший вариант для внедрения зависимостей на уровне C ++.
Я нашел решение этой проблемы, и я собираюсь рассмотреть его подробно, так как, вероятно, никто другой не пытался сделать такую сумасшедшую вещь!
Предположим, у вас есть два модули нативного узла. Это означает, что они живут в отдельных исполняемых файлах (.node). Один из них — модуль A, а другой — модуль B:
ModuleA:
class cppClass
{
public:
cppClass();
~cppClass();
// C++ stuff here
}; // !class cppClass
class cppClassWrap
: public node::ObjectWrap
{
public:
// used for initializing this class for Node/v8
static void Initialize(v8::Handle<Object> target);
// internal C++ data accessor
cppClass* GetWrapped() const { return internal_; };
// internal C++ data accessor
void SetWrapped(cppClass* n) { internal_ = n; };
private:
cppClassWrap();
cppClassWrap(cppClass*);
~cppClassWrap() { if (internal_) delete internal_; };
// JS stuff here
static Persistent<Function> constructor;
// JS c'tor
static NAN_METHOD(New);
// internal C++ data
cppClass* internal_;
}; // !class cppClassWrap
//-------------------------------------------------
// JS c'tor implementation
NAN_METHOD(cppClassWrap::New)
{
NanScope();
cppClassWrap* obj;
if (args.Length() == 0)
{
obj = new cppClass();
}
// **** NOTICE THIS! ****
// This is a special case when in JS land we initialize our class like: new cppClassWrap(null)
// It constructs the object with a pointer, pointing to nothing!
else if (args[0]->IsNull())
{
obj = new cppClass(nullptr);
}
else
{
//copy constructor for the JS side
obj = new cppClassWrap(ObjectWrap::Unwrap<cppClassWrap>(args[0]->ToObject())->GetWrapped());
}
obj->Wrap(args.This());
NanReturnValue(args.This());
}
С этого момента все, что вам нужно сделать, это, например, иметь Persistent
обрабатывать ModuleB
хранить копию конструктора ModuleA
Класс не в этом. Например, вы можете иметь метод с именем dependencies
и назовите это в JS как:
var cppClassWrap = require("ModuleA.node").cppClassWrap;
var moduleB = require("ModuleB.node").dependencies({
"moduleA" : function() {return new cppClassWrap(null); }
});
И сделано! у вас есть модуль внедрения на уровне C ++!