-
Notifications
You must be signed in to change notification settings - Fork 3
Limitations in Electron
Electron no longer supports external buffers (see issue). This makes it impossible to expose memory from within a Zig module to JavaScript code. Global variables will therefore not be accessible:
const std = @import("std");
pub const constant_number: i32 = 1234;
pub var variable_number: i32 = 4567;
pub fn printVariable() void {
std.debug.print("variable_number = {d} (Zig)\n", .{variable_number});
}
pub fn changeVariable() void {
variable_number = 1999;
}
require('node-zigar');
const test = require('../zig/test.zig');
console.log(test.constant_number);
console.log(test.variable_number);
1234
undefined
The option omitVariables
is by default true
on Electron. If
you override the default and make it false
, JavaScript would be able to see the initial value of
the variable. It would not be able to actually alter the variable. Nor would it see any
subsequent changes done on the Zig side:
require('node-zigar/cjs');
const test = require('../zig/test.zig?omit-variables=0');
console.log(`variable_number = ${test.variable_number} (JavaScript)`);
console.log('setting variable to 8888 in JavaScript');
test.variable_number = 8888;
test.printVariable();
console.log('setting variable to 1999 in Zig');
test.changeVariable();
test.printVariable();
console.log(`variable_number = ${test.variable_number} (JavaScript)`);
variable_number = 4567 (JavaScript)
setting variable to 8888 in JavaScript
variable_number = 4567 (Zig)
setting variable to 1999 in Zig
variable_number = 1999 (Zig)
variable_number = 8888 (JavaScript)
Node-zigar resorts to making a copy of the memory when it's blocked from creating an external buffer. This strategy does not impact pointers. Zig code would still receive the right addresses. For example, this example from the previous section works correctly in Electron:
const std = @import("std");
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
var allocator = gpa.allocator();
pub fn floatToString(num: f64) ![]const u8 {
return std.fmt.allocPrint(allocator, "{d}", .{num});
}
pub fn freeString(str: []const u8) void {
allocator.free(str);
}
const { floatToString, freeString } = require('./data-transfer-example-2.zig');
const array = floatToString(Math.PI);
console.log(array.string);
freeString(array);
3.141592653589793
The pointer that freeString()
receives is the one returned by floatToString()
.