Thanks Andrew! That is all very helpful. I'm still having a little bit of 
trouble on the buffers. The object that I'm wrapping has a field on it 
which is a std::vector<uint8_t>, and a method which returns that vector to 
me. This is one of the methods that I'm exposing to JS, and I would like it 
to return a Buffer, which I'm doing like this simplified example (in 
v0.10.23):

v8::HandleScope scope;
MyObject* object = node::ObjectWrap::Unwrap<MyObject>(args.This());
std::vector<uint8_t> my_data = object->my_data();
v8::Handle<v8::Object> buffer = 
node::Buffer::New(reinterpret_cast<char*>(my_data.data()), 
my_data.size()).handle_;
return scope.Close(buffer);

However when I do this I'm actually getting a SlowBuffer. In node_buffer.h 
it says I can construct a fast buffer by invoking New with a 
v8::Handle<v8::String>, but I believe this would mean copying over the 
data? Is that the only way to construct a fast (sliced) buffer?

Also this is returning a persistent handle, and I don't think I fully 
understand how to make sure those get cleaned up correctly - I just want 
the data to get collected when the user decides to throw away the reference 
to the buffer returned to them in javascript. Does that mean I have to make 
the reference weak, and supply a callback to be invoked when only weak 
references are held to the object? If that's the case, then it seems like I 
actually need to delete (in the C++ sense) the backing node::Buffer*, but 
since the callback only provides the char* data pointed at, I can't do that?

Last but not least - if the user does this in JS:
var object = new MyObject();
var myData = object.myData();
object = null;

Then object is eligible to get garbage collected, but myData has a pointer 
into data held by object. Does this mean, again, that I have to make a copy 
of the data every time someone calls myData()? Is there a more efficient 
method (shared pointers? something else?)

Sorry if some of that doesn't make sense - I'm having a hard time figuring 
out the proper way to do this.

Thanks!

On Thursday, December 12, 2013 9:43:29 AM UTC-8, Andrew Kelley wrote:
>
> I can't answer all of your questions but I can help with a couple:
>
> 2. setInternalFieldCount. See this page of v8 docs: 
> http://izs.me/v8-docs/classv8_1_1Object.html#a94e24494687ea499471d41e914eeb90d
>
> My understanding of this is that you setInternalFieldCount to some integer 
> (such as 3) and then you have that many slots with which to put stuff in. 
> You can then use SetInternalField(0, someValue) and GetInternalField(0) 
> where 0 is the index of the internal field. I think that 
> the node::ObjectWrap helper thing uses internal field index 0 under the 
> covers. So the fact that you have to setInternalFieldCount even though you 
> never use it is a leaky abstraction. I could be wrong; I haven't actually 
> looked at the node objectwrap code.
>
>
> 3. buffers.
>
> Here's a chat log of trevnorris helping me out with buffers: 
> https://gist.github.com/superjoe30/7198261
>
> 4. packaging
>
> It's generally considered convenient to bundle C library dependencies with 
> your node module. So you'd compile your depending library along with your 
> wrapper code all together, that way the user of your module does not 
> actually need that library installed on their system. This is not required 
> however, and if the dependency is huge and heavy it would probably make 
> more sense to depend on it dynamically instead of bundling it.
>
> 5. general tips
>
> Look at existing node addons for reference. TooTallNate specifically has a 
> bunch of good examples available on github to look at.
> For what it's worth here's a module I made: 
> https://github.com/superjoe30/node-groove
> It should by no means be taken as a perfect example; it's the first and 
> only addon I've made, but maybe it can help anyway.
>
> good luck!
>
> On Tuesday, December 10, 2013 5:39:59 PM UTC-5, AT wrote:
>>
>> Hey all,
>>
>> I'm just starting to write my first C++ addon for node and I'm finding 
>> that the documentation can be a little sparse at times. I had a few 
>> beginner questions for you all, in no particular order:
>>
>> 1) v8::Signatures - It seems like they're supposed to validate that 
>> functions are invoked on objects which can respond to that function, in 
>> case people use call/apply. A common pattern in the node code is to use 
>> NODE_SET_PROTOTYPE_METHOD macro to automatically use the correct signature, 
>> but it generates multiple signature objects that I believe are all 
>> identical, since they're based only on the template being supplied. So, 
>> instead of doing:
>>
>> NODE_SET_PROTOTYPE_METHOD(tpl, "function1", Function1)
>> NODE_SET_PROTOTYPE_METHOD(tpl, "function2", Function2)
>> NODE_SET_PROTOTYPE_METHOD(tpl, "function3", Function3)
>>
>> I could do:
>>
>> v8::Local<v8::Signature> signature = v8::Signature::New(tpl);
>> tpl->PrototypeTemplate()->Set(v8::String::NewSymbol("function1"), 
>> v8::FunctionTemplate::New(Function1, v8::Handle<v8::Value>(), signature));
>> tpl->PrototypeTemplate()->Set(v8::String::NewSymbol("function2"), 
>> v8::FunctionTemplate::New(Function2, v8::Handle<v8::Value>(), signature));
>> tpl->PrototypeTemplate()->Set(v8::String::NewSymbol("function3"), 
>> v8::FunctionTemplate::New(Function3, v8::Handle<v8::Value>(), signature));
>>
>> Is it correct to reuse the signature like this? Is it not worth doing so 
>> because of the extra verbosity?
>>
>> Also, what is the second parameter (`data`) passed in to 
>> FunctionTemplate::New? I took a look at v8.h but it was not described.
>>
>> 2) SetInternalFieldCount. I took at look at the following:
>>
>> http://stackoverflow.com/questions/16600735/what-is-an-internal-field-count-and-what-is-setinternalfieldcount-used-for
>>
>> https://groups.google.com/forum/#!searchin/v8-users/SetInternalFieldCount/v8-users/2LyzMXilUiM/OVQpWehDm9MJ
>>
>> and I still don't fully understand this. It seems like SetInternalField 
>> lets me associate arbitrary C++ objects with my JS objects, and 
>> SetInternalFieldCount just makes space for that many (void *)'s, but I 
>> don't think I understand the use case for this. In the node examples here:
>> http://nodejs.org/api/addons.html
>>
>> they call SetInternalFieldCount even though they don't set any internal 
>> fields. Indeed, when I run some of my own code and omit the 
>> SetInternalFieldCount(1) call, I get the following:
>> .node-gyp/0.10.16/src/node_object_wrap.h:71: void 
>> node::ObjectWrap::Wrap(v8::Handle<v8::Object>): Assertion 
>> `handle->InternalFieldCount() >0 ' failed.
>>
>> Why does this need to be a minimum of 1 if I have no internal fields? If 
>> I want to implement my own JS objects it seems cleaner to me to have my 
>> class which inherits from node::ObjectWrap to just have the necessary 
>> members on it there, instead of having them set as internal fields?
>>
>> 3) Buffers.
>>
>> The first result on google for making a Node buffer in C++ land is the 
>> following:
>>
>> http://www.samcday.com.au/blog/2011/03/03/creating-a-proper-buffer-in-a-node-c-addon/
>>
>> This post is from 2011 - is it still accurate? Looking through the Node 
>> source it seems that the structure is still the same as described in the 
>> article (slow buffer implemented in node_buffers.h, regular buffer 
>> implemented in JS land via buffer.js), but it seems so hacky to construct 
>> buffers this way. What if someone changes the global Buffer?
>>
>> One of the comments an the article alludes to Buffer::MakeFastBuffer() 
>> but I don't see this function in master. What I do see is SetupBufferJS:
>> https://github.com/joyent/node/blob/master/src/node_buffer.cc#L598
>> which looks like it takes a C++ land buffer and makes it more 
>> "node-like", but the methods it adds are different than the plain Buffer 
>> interface provided in buffer.js, so I don't think that's what I want either.
>>
>> 4) Packaging
>>
>> What are the packaging conventions / how do I ship my addon which depends 
>> on other libraries being present.
>>
>> For users who want to build from source:
>>
>> Should my library include the source of my dependency, and its 
>> dependencies, and so on, so that users who try to compile will get the 
>> versions that I'm building against?
>>
>> Should my library include none of my dependencies, and just include 
>> instructions (before running node-gyp, install xxx >= 1.0.0, install yyy <= 
>> 1.5.0, etc)
>>
>> For users who want to install from npm:
>>
>> Should my addon include pre-built binaries for the platforms that I plan 
>> on supporting?
>>
>> Should it just give instructions (have the following libs available, 
>> etc), and I can dynamically load those libraries?
>>
>> Sorry for the lengthy post - thanks in advance for all the help!
>>
>

-- 
-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

--- 
You received this message because you are subscribed to the Google Groups 
"nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to