我正在尝试为GJS中的chrome / firefox扩展编写native messaging host(因为它将依赖于已经在GJS中编写的代码)但遇到了一些障碍。我使用chrome-gnome-shell作为粗略模板,因为它也使用了GLib / Gio instrospection和GApplication,但它具有python struct
的优点,而我没有。
很快,本机消息传递主机通过stdin / stdout交换消息,这是一个Int32(4字节)长度,后跟一串utf-8编码的JSON。
chrome-gnome-shell使用GLib.IOChannel
set_encoding('utf-8')
和struct
来处理int32字节。我在GJS中使用该课程时遇到了麻烦,但没有struct
因此Gio.UnixInputStream
Gio.DataInputStream
包裹在put_int32()
(和输出对应物),read_int32()
/ { {1}}和put_string()
/ read_string()
。
显然我对我正在做的事情感到非常困惑。如果我调用Gio.DataInputStream.read_int32()
它会返回一个数字369098752
,所以我猜测int32没有被转换为常规数字。如果我打电话给Gio.DataInputStream.read_bytes(4, null).unref_to_array()
来获得ByteArray; ByteArray.toString()
返回'\ u0016',而ByteArray [0]返回'22',这似乎是实际长度。
关于将int32读取/写入数据流的一些指示,非常感谢。
chrome-gnome-shell引用:
答案 0 :(得分:0)
我不知道这是否是解决这个问题的最佳方法,但这就是我想出来的。
使用ByteArray导入的两个函数(从SO上的某处修改):
const ByteArray = imports.byteArray;
function fromInt32 (byteArray) {
var value = 0;
for (var i = byteArray.length - 1; i >= 0; i--) {
value = (value * 256) + byteArray[i];
}
return value;
};
function toInt32 (num) {
var byteArray = [0, 0, 0, 0];
for (var index_ = 0; index_ < byteArray.length; index_++) {
var byte = num & 0xff;
byteArray [index_] = byte;
num = (num - byte) / 256 ;
}
return ByteArray.fromArray(byteArray);
};
接收/发送:
const Gio = imports.gi.Gio;
// Receiving
let stdin = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({ fd: 0 })
});
let int32 = stdin.read_bytes(4, null).toArray();
let length = fromInt32(int32);
let data = stdin.read_bytes(length, null).toArray().toString();
let message = JSON.parse(data);
// Sending
let stdout = new Gio.DataOutputStream({
base_stream: new Gio.UnixOutputStream({ fd: 1 })
});
let data = JSON.stringify(message);
let int32 = toInt32(data.length);
stdout.write(int32, null);
stdout.put_string(data, null);
当然,您应该将这些包装在try-catch中,并且您可能希望将源连接到输入(您可以使用Gio.UnixInputStream):
let source = stdin.base_stream.create_source(null);
source.set_callback(onReceiveFunc);
source.attach(null);
答案 1 :(得分:0)
您可以像使用read_bytes()
和put_string()
一样使用Gio.DataOutputStream.put_int32()
和Gio.DataInputStream.read_int32()
。