第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何從WebAssembly函數(shù)返回JavaScript字符串

如何從WebAssembly函數(shù)返回JavaScript字符串

郎朗坤 2019-11-30 13:58:43
如何從WebAssembly函數(shù)返回JavaScript字符串?下列模塊可以用C(++)編寫嗎?export function foo() {  return 'Hello World!';}另外:我可以將其傳遞給JS引擎進(jìn)行垃圾回收嗎?
查看完整描述

3 回答

?
蝴蝶刀刀

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超8個贊

WebAssembly本身不支持字符串類型,它,而支撐件i32/ i64/ f32/ f64 值類型以及i8/ i16用于存儲。


您可以使用以下方法與WebAssembly實(shí)例進(jìn)行交互:


exports,您可以從JavaScript中調(diào)用WebAssembly,然后WebAssembly返回單個值類型。

imports 其中WebAssembly調(diào)用JavaScript,并具有所需的任意數(shù)量的值類型(注意:必須在模塊編譯時知道計(jì)數(shù),這不是數(shù)組,也不是可變參數(shù))。

Memory.buffer,ArrayBuffer可以使用(以及其他)索引Uint8Array。

這取決于您要執(zhí)行的操作,但似乎直接訪問緩沖區(qū)是最簡單的:


const bin = ...; // WebAssembly binary, I assume below that it imports a memory from module "imports", field "memory".

const module = new WebAssembly.Module(bin);

const memory = new WebAssembly.Memory({ initial: 2 }); // Size is in pages.

const instance = new WebAssembly.Instance(module, { imports: { memory: memory } });

const arrayBuffer = memory.buffer;

const buffer = new Uint8Array(arrayBuffer);

如果您的模塊具有start功能,那么它將在實(shí)例化時執(zhí)行。否則,您可能會調(diào)用一個導(dǎo)出,例如instance.exports.doIt()。


完成后,您需要獲取字符串大小+內(nèi)存中的索引,您還可以通過導(dǎo)出將其公開:


const size = instance.exports.myStringSize();

const index = instance.exports.myStringIndex();

然后,將其從緩沖區(qū)中讀取:


let s = "";

for (let i = index; i < index + size; ++i)

  s += String.fromCharCode(buffer[i]);

請注意,我正在從緩沖區(qū)讀取8位值,因此我假設(shè)字符串是ASCII。那就是std::string給你的東西(內(nèi)存中的索引就是.c_str()返回的東西),但是要暴露其他東西(例如UTF-8),您需要使用支持UTF-8的C ++庫,然后自己從JavaScript中讀取UTF-8,獲得代碼點(diǎn),然后使用String.fromCodePoint。


您還可以依靠以null終止的字符串,我在這里沒有這樣做。


您也可以使用TextDecoderAPI,一旦它獲得更廣泛的瀏覽器中創(chuàng)建一個ArrayBufferView到WebAssembly.Memory的buffer(這是ArrayBuffer)。


相反,如果您正在執(zhí)行從WebAssembly到JavaScript的日志記錄等操作,則可以公開Memory上述內(nèi)容,然后從WebAssembly聲明一個導(dǎo)入,該導(dǎo)入以size + position調(diào)用JavaScript。您可以將模塊實(shí)例化為:


const memory = new WebAssembly.Memory({ initial: 2 });

const arrayBuffer = memory.buffer;

const buffer = new Uint8Array(arrayBuffer);

const instance = new WebAssembly.Instance(module, {

    imports: {

        memory: memory,

        logString: (size, index) => {

            let s = "";

            for (let i = index; i < index + size; ++i)

                s += String.fromCharCode(buffer[i]);

            console.log(s);

    }

});

需要注意的是,如果您增加了內(nèi)存(通過使用JavaScript的JavaScript Memory.prototype.grow或使用grow_memory操作碼),則內(nèi)存將ArrayBuffer被清除,您需要重新創(chuàng)建。


垃圾收集器:WebAssembly.Module/ WebAssembly.Instance/ WebAssembly.Memory是由JavaScript引擎收集到的所有垃圾,但是這是一個相當(dāng)大的錘子。您可能希望使用GC字符串,而對于位于中的對象,目前尚無法實(shí)現(xiàn)WebAssembly.Memory。我們已經(jīng)討論了將來增加GC支持的問題。


查看完整回答
反對 回復(fù) 2019-11-30
?
哆啦的時光機(jī)

TA貢獻(xiàn)1779條經(jīng)驗(yàn) 獲得超6個贊

有一種更簡單的方法可以做到這一點(diǎn)。首先,您需要二進(jìn)制文件的實(shí)例:


const module = new WebAssembly.Module(bin);

const memory = new WebAssembly.Memory({ initial: 2 });

const instance = new WebAssembly.Instance(module, { imports: { memory: memory } });

然后,如果運(yùn)行console.log(instance),則幾乎在該對象的頂部,您將看到function AsciiToString。從C ++傳遞您的函數(shù),該函數(shù)返回字符串,您將看到輸出。對于這種情況,請查看此庫。


查看完整回答
反對 回復(fù) 2019-11-30
  • 3 回答
  • 0 關(guān)注
  • 761 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號