我试图创建一个包含libuv双工管道的节点插件,用于c ++和节点进程之间的通信。
我已经写完了课程,现在我正在测试它,但是,当我尝试打开管道时:
int fd = uv_fs_open(uv_default_loop(), obj->file_req, "MYFIFO", O_CREAT | O_RDWR, 0644, NULL);
我遇到了分段错误11。
这是我的班级实施:
#include <node.h>
#include <string>
#include <uv.h>
#include <queue>
using namespace v8;
const char* symbol_message = "message";
class rtSocket : public node::ObjectWrap
{
private:
public:
static Persistent<Function> constructor;
uv_pipe_t * readPipe, * writePipe;
uv_fs_t * file_req;
uv_mutex_t message_mutex;
uv_async_t message_async;
struct PipeMessage
{
unsigned int cb;
unsigned int value;
};
std::queue<PipeMessage*> message_queue;
rtSocket()
{
writePipe = NULL;
readPipe = NULL;
uv_mutex_init(&message_mutex);
}
~rtSocket()
{
/*uv_read_stop()???*/
uv_mutex_destroy(&message_mutex);
}
static Handle<Value> New( const Arguments & args)
{
HandleScope scope;
if (!args.IsConstructCall())
{
return ThrowException(v8::Exception::TypeError(
v8::String::New("Use the new operator to create instances of this object.")));
}
// Invoked as constructor: `new MyObject(...)`
rtSocket * obj = new rtSocket();
obj->message_async.data = obj;
uv_async_init(uv_default_loop(), &obj->message_async, rtSocket::EmitMessage);
obj->Wrap(args.This());
return args.This();
}
static Handle<Value> Connect(const Arguments & args)
{
HandleScope scope;
rtSocket * obj = ObjectWrap::Unwrap<rtSocket>(args.This());
int fd, r;
if (1 > args.Length() || !args[0]->IsString())
{
return ThrowException(Exception::TypeError(
String::New("First argument must be a string (FIFO name)")));
}
v8::String::Utf8Value s (args[0]->ToString());
std::string p( *s );
std::string writablePipeName, readablePipeName;
writablePipeName = readablePipeName = p;
writablePipeName.resize(writablePipeName.size()+1, 'W');
readablePipeName.resize(readablePipeName.size()+1, 'R');
//Open file system Pipe
fd = uv_fs_open(uv_default_loop(), obj->file_req, readablePipeName.c_str(), O_CREAT | O_RDWR, 0644, NULL);
//Initialize reading pipe
r = uv_pipe_init(uv_default_loop(), obj->readPipe, 0);
if (r)
{
return ThrowException(Exception::TypeError(
String::New("Impossible to initialize read pipe!!")));
}
//Open pipe
r = uv_pipe_open(obj->readPipe, fd);
if (r)
{
return ThrowException(Exception::TypeError(
String::New("Impossible to open read pipe!!")));
}
//Register callbacks
r = uv_read_start((uv_stream_t*)obj->readPipe, rtSocket::on_alloc_buffer, rtSocket::on_read);
if (r)
{
return ThrowException(Exception::TypeError(
String::New("Impossible to call read start!!")));
}
//Open file system Pipe
fd = uv_fs_open(uv_default_loop(), obj->file_req, writablePipeName.c_str(), O_CREAT | O_RDWR, 0644, NULL);
//Initialize reading pipe
r = uv_pipe_init(uv_default_loop(), obj->writePipe, 0);
if (r)
{
return ThrowException(Exception::TypeError(
String::New("Impossible to initialize write pipe!!")));
}
//Open pipe
r = uv_pipe_open(obj->writePipe, fd);
if (r)
{
return ThrowException(Exception::TypeError(
String::New("Impossible to open write pipe!!")));
}
//Don't register callbacks on writable pipe, write from js
return scope.Close(Undefined());
}
static void Init(Handle<Object> exports)
{
//Prepare constructor template
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->SetClassName(String::NewSymbol("rtSocket"));
NODE_SET_PROTOTYPE_METHOD(tpl, "Connect", Connect);
constructor = Persistent<Function>::New(tpl->GetFunction());
exports->Set(String::NewSymbol("rtSocket"), constructor);
}
};
Persistent<Function> rtSocket::constructor;
extern "C"
{
void init (v8::Handle<v8::Object> target)
{
rtSocket::Init(target);
}
NODE_MODULE(rtSocket, init)
}
很抱歉,但我认为这是必要的背景(EmitMessage,on_alloc_buffer和on_read并不是为了简单起见)。
我正在努力解决这个问题,我认为这与背景和范围有关,但不知道如何解决它。如果有人能够解释我做错了什么,那就太好了!
编辑:我试图猜测node-segfault-handler会发生什么,这是堆栈跟踪,但我不理解它抱怨的内容: