I am developing a NodeJS module and its file size is increasing dramatically, however I have realized that I can divide my module into two separate modules. When this happens only a few functions in my second module need to use internal C++ classes of my first module. Is it possible to somehow only pass the prototype of the first module to the second one?
Example:
Module A:
Has a class called cModuleA:
class cModuleA {
//declarations
data* pointer;
}
Module B:
Has about 100 function but only one of them needs to manipulate data* pointers. It needs to return cModuleA object as well (therefore it needs a prototype of cModuleA or be aware of cModuleA implementation)
I have tried to export symbols from the first module (dllimport/dllexport in windows) but I was just wondering if there is any better option to inject dependencies at C++ level.
I found a solution to this problem and I am going to go over it in detail since probably nobody else has attempted to do such a crazy thing!
Assume you have two native node modules. Meaning that they live in separate executable files (.node). One of them is moduleA and the other one is moduleB:
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());
}
From this point on, all you need to do is to for example have Persistent handle in ModuleB to store a copy of the constructor of ModuleA's class c'tor in it. For example you can have a method called dependencies and call it in JS like:
var cppClassWrap = require("ModuleA.node").cppClassWrap;
var moduleB = require("ModuleB.node").dependencies({
"moduleA" : function() {return new cppClassWrap(null); }
});
And done! you have module injection at C++ level!