Я пытаюсь написать программу Swift, которая запускает JS через JavaScriptCore. Я sh хочу разделить память между обеими частями моей программы так, чтобы JS записывал в буфер типизированного массива, созданный в Swift, а Swift считывал и записывал в него впоследствии. Это будет своего рода буфер команд.
Например, вот некоторый псевдокод, который приблизительно представляет то, что я планирую сделать:
// js
let buf;
let i = 0;
setup() {
buf = new Uint8Array(mem.alloc(N_BYTES));
}
frame() {
i = 0;
buf[i++] = some_command_enum;
}
// swift
func alloc(bytes : Int) -> the_memory {
// allocate bytes uints and save the memory here
// save a reference to the memory here
// return the memory to use in JS
}
Проблема в том, что всякий раз, когда я пытаюсь на самом деле добавление реализации к allo c, JS сообщает через исключение, что функция не определена, что означает, что что-то не так с тем, как я делаю вещи. Невозвратные функции - это нормально, поэтому я отказался.
Это моя неправильная реализация (см. Комментарии):
// swift
@objc protocol JSMemoryExports: JSExport {
static func alloc(_ byte_count: Int) -> JSObjectRef
static func free(_ memory: JSObjectRef)
}
class JSMemory: NSObject, JSMemoryExports {
// What is the correct return type?
class func alloc(_ byte_count: Int) -> JSObjectRef {
// temp
let jsContext = JS_Controller.js.ctx!
print("BYTE_COUNT", byte_count)
// allocating a typed array
let arr = JSObjectMakeTypedArray(jsContext.jsGlobalContextRef!, kJSTypedArrayTypeUint8Array, byte_count, nil)
// just testing here to see how I'd write to this buffer (Note: is this the fastest way, or is all this memory binding slow?:
// getting the raw bytes
let ptr = JSObjectGetTypedArrayBytesPtr(jsContext.jsGlobalContextRef!, arr, nil)
//let buf = JSObjectGetTypedArrayBuffer(jsContext.jsGlobalContextRef, arr, nil)
let u8Ptr = ptr!.bindMemory(to: UInt8.self, capacity: byte_count)
//u8Ptr[0] = 5
return arr!
}
}
...
jsContext["mem"] = JSMemory.self
// js
const buf = new Uint8Array(mem.alloc(8)) // JS Exception: TypeError: mem.alloc is not a function. (In 'mem.alloc(8)', 'mem.alloc' is undefined)
Я видел варианты функций привязка, которая использует какой-то атрибут @convention
. Должен ли я использовать это вместо этого?
Как правильно поступить?