真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

AWTKWEB版移植方法是什么

本篇內(nèi)容主要講解“ AWTK WEB版移植方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“ AWTK WEB版移植方法是什么”吧!

成都創(chuàng)新互聯(lián)公司專注于企業(yè)成都全網(wǎng)營銷、網(wǎng)站重做改版、景東網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、html5、商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價格優(yōu)惠性價比高,為景東等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

一、命令行參數(shù)

  • 1.EXPORTED_FUNCTIONS 用于導(dǎo)出應(yīng)用程序中C的函數(shù)供JS調(diào)用。如:

-s EXPORTED_FUNCTIONS="['_awtk_web_init']"

函數(shù)名前面要加下劃線,比如函數(shù)名為awtk_web_init,導(dǎo)出的名稱則為_awtk_web_init。

對于小的項(xiàng)目,導(dǎo)出的函數(shù)很少,直接寫在命令行也是可以的。對于大的項(xiàng)目,導(dǎo)出的函數(shù)很多,應(yīng)該把內(nèi)容寫到文件中,通過@符合告訴emcc從文件中讀取導(dǎo)出的函數(shù),這樣維護(hù)起來會方便很多。如:

-s EXPORTED_FUNCTIONS=@configs/export_app_funcs.json

configs/export_app_funcs.json的內(nèi)容:

[
    "_awtk_web_init",
    "_awtk_web_deinit",
    "_awtk_web_main_loop_step",
    "_awtk_web_on_key_down",
    "_awtk_web_on_key_up",
    "_awtk_web_on_wheel",
    "_awtk_web_on_pointer_down",
    "_awtk_web_on_pointer_move",
    "_awtk_web_on_im_commit",
    "_awtk_web_on_pointer_up"
]
  • 2.EXTRA_EXPORTED_RUNTIME_METHODS 用于導(dǎo)出runtime中的函數(shù)供JS調(diào)用。如:

-s EXTRA_EXPORTED_RUNTIME_METHODS ="['cwrap']"

同理,將它的內(nèi)容放在文件中,也是更可取的方法。如:

-s EXTRA_EXPORTED_RUNTIME_METHODS=@configs/export_runtime_funcs.json

configs/export_runtime_funcs.json的內(nèi)容:

[
    "ccall",
    "cwrap",
    "addFunction",
    "removeFunction",
    "addOnPostRun",
    "addOnInit",
    "addOnExit",
    "addOnPreMain",
    "UTF8ToString"
]
  • 3.調(diào)試和優(yōu)化

對于大的項(xiàng)目,調(diào)試版本最好不要加-g標(biāo)志,產(chǎn)生的代碼實(shí)在太大了,可能讓瀏覽器處于假死狀態(tài),根本沒法調(diào)試。用缺省生成的代碼調(diào)試基本上就OK了。

發(fā)布版本建議加-Os,代碼體積會大大減小,而且它會把數(shù)據(jù)獨(dú)立出來,提高加載的速度。

  • 4.調(diào)試的宏。

emcc生成的常量數(shù)據(jù)的首地址并不會按32bit/64bit對齊,AWTK就踩到這個坑里了,SAFE_HEAP宏有助于發(fā)現(xiàn)這個問題。建議定義下列這些宏:

-DSAFE_HEAP=1 -DASSERTIONS=1 -DSTACK_OVERFLOW_CHECK=1

后來我給AWTK的常量全加上了對齊的屬性:

#ifdef _MSC_VER
#define TK_CONST_DATA_ALIGN(v) __declspec(align(8)) v
#else
#define TK_CONST_DATA_ALIGN(v) v __attribute__((aligned(8)))
#endif /*_MSC_VER*/
TK_CONST_DATA_ALIGN(const unsigned char data_a_b_c_any[]) = { 
0x08,0x00,0x00,0x01,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x2d,0x62,0x2d,0x63,0x2e,0x61,0x6e,
0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x61,0x62,0x63,0x0a,0x00,0x00,0x00,0x00,};/*52*/
  • 5.命令行參數(shù)過長的問題

對于一個大型項(xiàng)目,在Windows平臺下,命令行參數(shù)很容易超長。最簡單的辦法就是將emcc的參數(shù)寫入文件中,通過@符合告訴emcc從文件讀取。如:

emcc -v @args.txt

二、C語言調(diào)用JS的函數(shù)

  • 1.頭文件

包含emscripten.h頭文件,它提供了一些方法,讓C語言調(diào)用JS的函數(shù)。

#include 
  • 2.通過emscripten_run_script調(diào)用。

如:

emscripten_run_script("alert('hi')");
  • 3.通過EM_JS/EM_ASM調(diào)用。

如:

#include 

EM_JS(void, call_alert, (), {
  alert('hello world!');
  throw 'all done';
});

int main() {
  call_alert();
  return 0;
}
#include 

int main() {
  EM_ASM(
    alert('hello world!');
    throw 'all done';
  );
  return 0;
}
    1. 通過EM_ASM_INT之類的宏調(diào)用。

這是最快也是最簡單的調(diào)用方式,AWTK里基本上都是采用這種方式調(diào)用的。如:

C端代碼:

static ret_t vgcanvas_web_save(vgcanvas_t *vgcanvas) {
  int32_t ret = EM_ASM_INT({ return VGCanvas.save(); }, 0); 

  return ret ? RET_OK : RET_FAIL;
}

JS端代碼:

VGCanvas.save = function () {
  VGCanvas.ctx.save();

  return true;
}

**傳遞數(shù)值參數(shù)也非常簡單。**如:

C端代碼:

static ret_t vgcanvas_web_move_to(vgcanvas_t *vgcanvas, float_t x, float_t y) {
  EM_ASM_INT({ return VGCanvas.moveTo($0, $1); }, x, y);
    
  return RET_OK;
}

JS端代碼:

VGCanvas.moveTo = function (x, y) {
  VGCanvas.ctx.moveTo(x, y);
  
  return true;
}

傳遞字符串參數(shù)就麻煩一點(diǎn)了。如:

C端代碼:

static ret_t vgcanvas_web_set_text_align(vgcanvas_t *vgcanvas,
                                         const char *text_align) {
  EM_ASM_INT({ return VGCanvas.setTextAlign($0); }, text_align);
  return RET_OK;
}

JS端代碼:

VGCanvas.setTextAlign = function (value) {
  VGCanvas.ctx.textAlign = pointerToString(value);

  return true;
}

字符串參數(shù)傳遞到JS函數(shù)里時,JS函數(shù)拿到的內(nèi)存地址的偏移量,需要把它解碼出來,生成JS的字符串對象。pointerToString函數(shù)是這樣實(shí)現(xiàn)的:

function pointerToString(pointer) {
  return pointer && Module.UTF8ToString(pointer, 1024) || null;
}

Module.UTF8ToString函數(shù)需要在前面介紹的EXTRA_EXPORTED_RUNTIME_METHODS中導(dǎo)出才能使用。

AWTK中還用了二進(jìn)制數(shù)據(jù)作為參數(shù),網(wǎng)上沒有見到相關(guān)的例子,只好自己去看代碼研究了。AWTK里需要把位圖數(shù)據(jù)(rgba顏色值),傳遞到JS中,再設(shè)置到畫布里。具體做法是這樣的:

VGCanvas.updateMutableImage = function (id) {
  let mutableImage = ImageCache.get(id);

  let w = mutableImage.width;        
  let h = mutableImage.height;       
  let size = mutableImage.width * mutableImage.height;
  let start = mutableImage.addr >> 2;
  let end = start + size; 
  let array = Module.HEAP32.subarray(start, end);
  let ctx = mutableImage.getContext('2d');
  let imageData = ctx.getImageData(0, 0, w, h);
  let data = new Int32Array(imageData.data.buffer);

  for(let i = 0; i < size; i++) {
    data[i] = array[i];
  }                                         
  ctx.putImageData(imageData, 0, 0, 0, 0, w, h);

  return true;
}

mutableImage.addr是rgba數(shù)據(jù)的地址,它是用malloc分配出來的,我看了malloc函數(shù)的實(shí)現(xiàn),它就相對于Module.HEAP32的字節(jié)數(shù)偏移量。由于HEAP32是4字節(jié)數(shù)據(jù),在作為偏移量使用時,需要右移2位:

  let start = mutableImage.addr >> 2;

再通過subarray從HEAP32中獲取這段數(shù)據(jù):

  let array = Module.HEAP32.subarray(start, end);

另外這里值得一提的是,imageData.data是Int8Array,要轉(zhuǎn)換成Int32Array,可以用下列方式:

  let imageData = ctx.getImageData(0, 0, w, h);
  let data = new Int32Array(imageData.data.buffer);

按下面這種方式,則是把每一個元素從8bit擴(kuò)展成32bit了。

  let imageData = ctx.getImageData(0, 0, w, h);
  let data = new Int32Array(imageData.data);

三、JS調(diào)用C的函數(shù)

要在JS里調(diào)用C的函數(shù),一般用Module.cwrap包裝一下,它需要提供以下參數(shù):

  • 函數(shù)名

  • 返回值

  • 參數(shù)列表

參數(shù)和返回值的類型有:

  • number

  • string

  • array

如:

Awtk._onImCommit = Module.cwrap('awtk_web_on_im_commit', 'number', ['string', 'number']);

Awtk.onImCommit = function (text, timestamp) {
  return Awtk._onImCommit(text, timestamp);
}

常見的用法的在文檔中都有清楚的說明,這里不再贅述。如果參數(shù)是一個回調(diào)函數(shù),就稍微麻煩一點(diǎn)。

  • 1.要導(dǎo)出addFunction/removeFunction(參考前面)

  • 2.要指定參數(shù)RESERVED_FUNCTION_POINTERS。

如:

-s RESERVED_FUNCTION_POINTERS=1000
  • 3.調(diào)用addFunction把函數(shù)轉(zhuǎn)成一個number,再作為參數(shù)傳入。

如:

widget_on(this.nativeObj, type, Module.addFunction(wrap_on_event(on_event)), ctx);

最麻煩的是函數(shù)用完之后,要調(diào)用removeFunction把函數(shù)從表里移出,對于同步調(diào)用的回調(diào)函數(shù)這沒有什么問題,但是對異步調(diào)用函數(shù),特別是多次調(diào)用的異步函數(shù),什么時候可以移出只有C代碼里才知道,所以需要在C代碼里添加處理。如:

#ifdef AWTK_WEB_JS
#include 
#endif /*AWTK_WEB_JS*/

static ret_t emitter_item_destroy(emitter_item_t* iter) {
  if (iter->on_destroy) {
    iter->on_destroy(iter);
  }

#ifdef AWTK_WEB_JS
  EM_ASM_INT({ return TBrowser.releaseFunction($0); }, iter->handler);
#endif /*AWTK_WEB_JS*/

  memset(iter, 0x00, sizeof(emitter_item_t));
  TKMEM_FREE(iter);

  return RET_OK;
}

到此,相信大家對“ AWTK WEB版移植方法是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!


分享文章:AWTKWEB版移植方法是什么
轉(zhuǎn)載來源:http://weahome.cn/article/jhgiei.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部