{"id":349,"date":"2023-11-16T12:59:34","date_gmt":"2023-11-16T04:59:34","guid":{"rendered":"https:\/\/blog.quantoyo.com\/?p=349"},"modified":"2023-11-16T12:59:34","modified_gmt":"2023-11-16T04:59:34","slug":"webassembly-wasm%e5%af%a6%e4%bd%9c","status":"publish","type":"post","link":"https:\/\/blog.quantoyo.com\/?p=349","title":{"rendered":"WebAssembly (wasm)\u5be6\u4f5c"},"content":{"rendered":"\n<p>Emscripten \u652f\u63f4 main \u4f5c\u70ba\u8d77\u9ede\u7684\u57f7\u884c\u65b9\u5f0f\uff0c\u4f46\u5be6\u969b\u4f7f\u7528\u4e0a\u9084\u662f\u6703\u4ee5\u76f4\u63a5\u547c\u53ebfunction \u70ba\u4e3b\uff0c\u5be6\u969b\u61c9\u7528\u4e0a\u6703\u4ee5\u9700\u8981\u5927\u91cf\u904b\u7b97\u7684\u90e8\u5206\u70ba\u4e3b\uff0c\u53ef\u4ee5\u52a0\u901f\u7db2\u9801\u7684\u904b\u7b97\uff0c\u4e5f\u53ef\u4ee5\u5c07\u4e0d\u60f3\u516c\u958b\u7684\u7a0b\u5f0f\u78bc\u96b1\u85cf\u5176\u4e2d\u3002<\/p>\n\n\n\n<!--more-->\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6e2c\u8a66C\u8a9e\u8a00\u6642\uff0c\u53ef\u4ee5\u4f7f\u7528 main function \u642d\u914d\u7c21\u55ae\u7684\u6307\u4ee4\u6e2c\u8a66\uff0c\u65b9\u4fbf\u958b\u767c\uff0c\u4ee5\u4e0b\u662f\u6e2c\u8a66\u6642\u4f7f\u7528\u7684C++\u5167\u5bb9(encode_decode.cpp)\uff0c\u5c07\u5176\u653e\u5728\u96a8\u4fbf\u4e00\u500b\u8cc7\u6599\u593e\u5373\u53ef\u3002<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code has-light-gray-background-color has-background has-small-font-size\"><code>#include &lt;cstdlib>\n#include &lt;cstring>\n#include &lt;string>   \/\/string\n#include &lt;sstream>  \/\/string buffer\n#include &lt;iomanip>  \/\/int_to_hex\n#include &lt;cctype>   \/\/toUpper\n\n\/\/ If this is an Emscripten (WebAssembly) build then...\uff08\u56e0\u70ba\u53ea\u6709\u7528emcc \u624d\u6703\u6709\u9019\u500b\u6a19\u982d\u6a94\uff09\n#ifdef __EMSCRIPTEN__\n  #include &lt;emscripten.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" { \/\/ So that the C++ compiler does not rename our function names\uff08\u70ba\u4e86\u652f\u63f4C\u51fd\u5f0f\u5eab\u5167\u7684\u51fd\u5f0f\uff09\n#endif\n\n\/\/\u8f03\u5feb\u901f\u7684\u8f49\u5927\u5beb\u65b9\u5f0f\nchar ascii_toupper_char(char c) {\n    return ('a' &lt;= c &amp;&amp; c &lt;= 'z') ? c^0x20 : c;    \/\/ ^ autovectorizes to PXOR: runs on more ports than paddb\n}\n\n\/\/\u8dd1\u904e\u6574\u500b\u5b57\u4e32\n\/\/ gcc can only auto-vectorize loops when the number of iterations is known before the first iteration.  strlen gives us that\nsize_t strtoupper_autovec(char *dst, const char *src) {\n    size_t len = strlen(src);\n      \/\/ printf(\"strlen = %d\\n\",len);\n    for (size_t i=0 ; i&lt;len ; ++i) {\n        dst&#91;i] = ascii_toupper_char(src&#91;i]);  \/\/ gcc does the vector range check with psubusb \/ pcmpeqb instead of pcmpgtb\n    }\n    return len;\n}\n\n#ifdef __EMSCRIPTEN__\n  EMSCRIPTEN_KEEPALIVE\n#endif\n  int encode(char* tmp_cmds, char* tmp_return)\n  {\n    size_t cmds_length = strlen(tmp_cmds);\n    std::stringstream transbuff;\n\t\tfor(int x=0; x &lt; cmds_length; x++) {\n      int c1 = 255 - tmp_cmds&#91;x];\n      std::stringstream tmp_sb;\n      tmp_sb &lt;&lt; std::hex &lt;&lt; c1;\n      char convertUpper&#91;] = \"FF\";\n      std::string s(tmp_sb.str());\n      tmp_sb.str(\"\");\n      const char* strSource = s.c_str(); \n      strtoupper_autovec(convertUpper,strSource);\n      transbuff &lt;&lt; convertUpper;\n\t\t}\n    std::string revbuff(transbuff.str());\n    transbuff.str(\"\");\n    strcpy(tmp_return, revbuff.c_str());\n    return 1;\n  }\n\n#ifdef __EMSCRIPTEN__\n  EMSCRIPTEN_KEEPALIVE\n#endif\n  int decode(char* tmp_cmds, char* tmp_return)\n  {\n    size_t cmds_length = strlen(tmp_cmds);\n    std::string revbuff(tmp_cmds);\n    std::stringstream tmp_result;\n    std::string tmpHex;\n    char * p;\n    int num = 0;\n\t\tfor(int x = 0; x &lt; cmds_length; x = x + 2) {\n      tmpHex = revbuff.substr(x,2);\n      num = strtol(tmpHex.c_str(), &amp;p, 16);\n      num = 255 - num;\n      tmp_result &lt;&lt; (char)num;\n\t\t}\n    strcpy(tmp_return, tmp_result.str().c_str());\n    tmp_result.str(\"\");\n    return 1;\n  }\n#ifdef __cplusplus\n}\n\n\n\/\/\u7de8\u8b6f\u6210\u7db2\u9801\u7528\u6a94\u6848\uff0c\u6ce8\u610f_free _malloc \u8981\u6307\u5b9a\u4e0d\u7136\u4e0d\u80fd\u7528(\u8ddf\u66f8\u4e0a\u4e0d\u540c)\n\/\/emcc encode_decode.cpp -o encoder.js -s EXTRA_EXPORTED_RUNTIME_METHODS=&#91;'ccall','UTF8ToString'] -s 'EXPORTED_FUNCTIONS=&#91;\"_free\",\"_malloc\"]'\n\/\/\u76f4\u63a5\u6e2c\u8a66\n\/\/ emcc encode_decode.cpp -o encode.html\nint main(){\n\tchar a&#91;] = \"THIS is test msg 12345\";\n  int cmds_length = sizeof(a)\/sizeof(char) - 1;\n  char b&#91;cmds_length * 2];\n\tprintf(\"origin: %s\\n\", a);\n\tencode(a,b);\n  size_t cmds_len = strlen(b);\n\tprintf(\"encode: %s\\n\", b);\n  int encode_length = sizeof(b)\/sizeof(char) - 1;\n  char c&#91;encode_length \/ 2];\n  decode(b,c);\n\tprintf(\"decode: %s\\n\", c);\n\treturn 0;\n}\n\n#endif\n<\/code><\/pre>\n\n\n\n<p>\u5728\u78ba\u8a8d Emscripten \u5b89\u88dd\u6b63\u5e38\u5f8c\uff0c\u5728\u9019\u500b\u8cc7\u6599\u593e\u4f7f\u7528\u4ee5\u4e0b\u6307\u4ee4<\/p>\n\n\n\n<pre class=\"wp-block-code has-light-gray-background-color has-background has-small-font-size\"><code>emcc encode_decode.cpp -o encode.html\n\n\u8f38\u51fa\u6307\u5b9a\u70bahtml \u578b\u614b\u6642\uff0c\u6703\u7522\u751f\u51fa\u4e00\u500b\u53ef\u4ee5\u76f4\u63a5\u6253\u958b\u6e2c\u8a66\u7528\u7684\u7db2\u9801\u8207\u76f8\u95dc\u6a94\u6848\uff0c\u4ee5\u4e0a\u6307\u4ee4\u6703\u7522\u751f\u51fa\nencode.html\nencode.js\nencode.wasm\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-1.png\" alt=\"\" class=\"wp-image-350\" width=\"296\" height=\"116\" srcset=\"https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-1.png 642w, https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-1-300x118.png 300w, https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-1-150x59.png 150w\" sizes=\"auto, (max-width: 296px) 100vw, 296px\" \/><\/figure>\n\n\n\n<p>\u63a5\u8457\u8981\u4f7f\u7528python \u5728\u6b64\u76ee\u9304\u4e0b\u958b\u555f\u7c21\u55ae\u7684web server <\/p>\n\n\n\n<pre class=\"wp-block-code has-light-gray-background-color has-background has-small-font-size\"><code>python -m http.server 8080<\/code><\/pre>\n\n\n\n<p>\u5c31\u53ef\u4ee5\u5728\u700f\u89bd\u5668\u7db2\u5740\u4e2d\u8f38\u5165 \u201chttp:\/\/localhost:8080\/encode.html\u201d \u4f86\u6e2c\u8a66\u525b\u525b\u6240\u5beb\u7684\u7a0b\u5f0f\u78bc\uff0c\u56e0\u70ba\u525b\u525b\u7684\u7a0b\u5f0f\u78bc\u5167\u5305\u542b\u4e86main function\uff0c\u6253\u958b\u5f8c\u6703\u81ea\u52d5\u57f7\u884c\uff0c\u4e26\u5c07\u7a0b\u5f0f\u5167\u7684printf \u6240\u8f38\u51fa\u7684\u6587\u5b57\u5370\u5728\u7db2\u9801\u4e0a\uff0c\u57f7\u884c\u5167\u5bb9\u5982\u4e0b<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1938\" height=\"980\" src=\"https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-2.png\" alt=\"\" class=\"wp-image-351\" srcset=\"https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-2.png 1938w, https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-2-300x152.png 300w, https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-2-150x76.png 150w, https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-2-768x388.png 768w, https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-2-1536x777.png 1536w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/figure>\n\n\n\n<p>\u81f3\u6b64\uff0c\u5df2\u7d93\u5b8c\u6210\u6700\u57fa\u672c\u7684wasm \u6d41\u7a0b<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5982\u679c\u60f3\u5728\u7db2\u9801\u4e2d\u4f7f\u7528encode \/ decode \u7b49function\uff0c\u9700\u8981\u505a\u4ee5\u4e0b\u8abf\u6574<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u5c07\u4e0a\u8ff0\u7a0b\u5f0f\u78bc\u5167\u7684main function \u79fb\u9664<\/li>\n\n\n\n<li>\u53e6\u5916\u5beb\u4e00\u4efdhtml \/ js \u4f86\u8b80\u53d6\u4e26\u4f7f\u7528 wasm<\/li>\n\n\n\n<li>\u4fee\u6539\u7de8\u8b6f\u65b9\u5f0f\uff0c\u4f7f\u5176\u4e0d\u7522\u751f\u51fahtml\u6a94\u6848<\/li>\n<\/ol>\n\n\n\n<p>\u8abf\u6574\u5f8c\u7684 encode_decode.cpp\u7a0b\u5f0f\u78bc<\/p>\n\n\n\n<pre class=\"wp-block-code has-light-gray-background-color has-background has-small-font-size\"><code>#include &lt;cstdlib>\n#include &lt;cstring>\n#include &lt;string>   \/\/string\n#include &lt;sstream>  \/\/string buffer\n#include &lt;iomanip>  \/\/int_to_hex\n#include &lt;cctype>   \/\/toUpper\n\n\/\/ If this is an Emscripten (WebAssembly) build then...\uff08\u56e0\u70ba\u53ea\u6709\u7528emcc \u624d\u6703\u6709\u9019\u500b\u6a19\u982d\u6a94\uff09\n#ifdef __EMSCRIPTEN__\n  #include &lt;emscripten.h>\n#endif\n\n#ifdef __cplusplus\nextern \"C\" { \/\/ So that the C++ compiler does not rename our function names\uff08\u70ba\u4e86\u652f\u63f4C\u51fd\u5f0f\u5eab\u5167\u7684\u51fd\u5f0f\uff09\n#endif\n\n\/\/\u8f03\u5feb\u901f\u7684\u8f49\u5927\u5beb\u65b9\u5f0f\nchar ascii_toupper_char(char c) {\n    return ('a' &lt;= c &amp;&amp; c &lt;= 'z') ? c^0x20 : c;    \/\/ ^ autovectorizes to PXOR: runs on more ports than paddb\n}\n\n\/\/\u8dd1\u904e\u6574\u500b\u5b57\u4e32\n\/\/ gcc can only auto-vectorize loops when the number of iterations is known before the first iteration.  strlen gives us that\nsize_t strtoupper_autovec(char *dst, const char *src) {\n    size_t len = strlen(src);\n      \/\/ printf(\"strlen = %d\\n\",len);\n    for (size_t i=0 ; i&lt;len ; ++i) {\n        dst&#91;i] = ascii_toupper_char(src&#91;i]);  \/\/ gcc does the vector range check with psubusb \/ pcmpeqb instead of pcmpgtb\n    }\n    return len;\n}\n\n#ifdef __EMSCRIPTEN__\n  EMSCRIPTEN_KEEPALIVE\n#endif\n  int encode(char* tmp_cmds, char* tmp_return)\n  {\n    size_t cmds_length = strlen(tmp_cmds);\n    std::stringstream transbuff;\n\t\tfor(int x=0; x &lt; cmds_length; x++) {\n      int c1 = 255 - tmp_cmds&#91;x];\n      std::stringstream tmp_sb;\n      tmp_sb &lt;&lt; std::hex &lt;&lt; c1;\n      char convertUpper&#91;] = \"FF\";\n      std::string s(tmp_sb.str());\n      tmp_sb.str(\"\");\n      const char* strSource = s.c_str(); \n      strtoupper_autovec(convertUpper,strSource);\n      transbuff &lt;&lt; convertUpper;\n\t\t}\n    std::string revbuff(transbuff.str());\n    transbuff.str(\"\");\n    strcpy(tmp_return, revbuff.c_str());\n    return 1;\n  }\n\n#ifdef __EMSCRIPTEN__\n  EMSCRIPTEN_KEEPALIVE\n#endif\n  int decode(char* tmp_cmds, char* tmp_return)\n  {\n    size_t cmds_length = strlen(tmp_cmds);\n    std::string revbuff(tmp_cmds);\n    std::stringstream tmp_result;\n    std::string tmpHex;\n    char * p;\n    int num = 0;\n\t\tfor(int x = 0; x &lt; cmds_length; x = x + 2) {\n      tmpHex = revbuff.substr(x,2);\n      num = strtol(tmpHex.c_str(), &amp;p, 16);\n      num = 255 - num;\n      tmp_result &lt;&lt; (char)num;\n\t\t}\n    strcpy(tmp_return, tmp_result.str().c_str());\n    tmp_result.str(\"\");\n    return 1;\n  }\n#ifdef __cplusplus\n}\n\n\/\/\u7de8\u8b6f\u6210\u7db2\u9801\u7528\u6a94\u6848\uff0c\u6ce8\u610f_free _malloc \u8981\u6307\u5b9a\u4e0d\u7136\u4e0d\u80fd\u7528(\u8ddf\u66f8\u4e0a\u4e0d\u540c)\n\/\/emcc encode_decode.cpp -o encoder.js -s EXTRA_EXPORTED_RUNTIME_METHODS=&#91;'ccall','UTF8ToString'] -s 'EXPORTED_FUNCTIONS=&#91;\"_free\",\"_malloc\"]'\n\n#endif<\/code><\/pre>\n\n\n\n<p>\u53e6\u5916\u6e96\u5099\u4e00\u500b test_encoder.html\uff0c\u5167\u5bb9\u5982\u4e0b<\/p>\n\n\n\n<pre class=\"wp-block-code has-light-gray-background-color has-background has-small-font-size\"><code>&lt;!DOCTYPE html>\n&lt;html>\n  &lt;head>\n    &lt;title>Edit Product&lt;\/title>\n    &lt;meta charset=\"utf-8\"\/>\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    &lt;link rel=\"stylesheet\" href=\"https:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/4.1.0\/css\/bootstrap.min.css\">\n    &lt;script src=\"https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/3.3.1\/jquery.min.js\">&lt;\/script>\n    &lt;script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/popper.js\/1.14.0\/umd\/popper.min.js\">&lt;\/script>\n    &lt;script src=\"https:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/4.1.0\/js\/bootstrap.min.js\">&lt;\/script>\n  &lt;\/head>\n  &lt;body onload=\"initializePage()\">\n    &lt;div class=\"container\">\n      &lt;h1>Edit Product&lt;\/h1>\n\n      &lt;div id=\"errorMessage\" class=\"alert alert-danger\" role=\"alert\" style=\"display:none;\">\n      &lt;\/div>\n\n      &lt;div class=\"form-group\">\n        &lt;label for=\"name\">Cmd:&lt;\/label>\n        &lt;input type=\"text\" class=\"form-control\" id=\"cmd\">\n      &lt;\/div>\n      &lt;button type=\"button\" class=\"btn btn-primary\" onclick=\"onClickEncode()\">Encode&lt;\/button>\n      &lt;div class=\"form-group\">\n        &lt;label for=\"name\">Encode:&lt;\/label>\n        &lt;input type=\"text\" class=\"form-control\" id=\"encodeCmd\">\n      &lt;\/div>\n      &lt;button type=\"button\" class=\"btn btn-primary\" onclick=\"onClickDecode()\">Decode&lt;\/button>\n      &lt;div class=\"form-group\">\n        &lt;label for=\"name\">Decode:&lt;\/label>\n        &lt;input type=\"text\" class=\"form-control\" id=\"decodeCmd\">\n      &lt;\/div>\n    &lt;\/div>\n\n    &lt;script src=\"test_encoder.js\">&lt;\/script>\n    &lt;script src=\"encoder.js\">&lt;\/script>\n  &lt;\/body>\n&lt;\/html>\n<\/code><\/pre>\n\n\n\n<p>\u8207\u4e00\u4efdtest_encoder.js\uff0c\u5167\u5bb9\u5982\u4e0b<\/p>\n\n\n\n<pre class=\"wp-block-code has-light-gray-background-color has-background has-small-font-size\"><code>const initialData = {\n  name: \"THIS is test msg 12345\"\n};\n\nfunction initializePage() {\n  document.getElementById(\"cmd\").value = initialData.name;\n}\n\nfunction onClickEncode(){\n  var start = Date.now();\n  var cmd = document.getElementById(\"cmd\").value;\n  var encodedCmd = encode(cmd);\n  document.getElementById(\"encodeCmd\").value = encodedCmd;\n}\n\nfunction onClickDecode(){\n  var start = Date.now();\n  var cmd = document.getElementById(\"encodeCmd\").value;\n  var decodedCmd = decode(cmd);\n  document.getElementById(\"decodeCmd\").value = decodedCmd;\n}\n\nfunction encode(cmd) {\n  let result = \"\";\n  const resultPointer = Module._malloc((cmd.length +1) * 2);  \/\/\u53d6\u5f97\u4e00\u584a\u8a18\u61b6\u9ad4\u7d66\u56de\u50b3\u7684\u6307\u6a19\u4f7f\u7528\n  const isValid = Module.ccall('encode',        \/\/C++ \u5167\u7684\u51fd\u5f0f\u540d\u7a31\n      'number',                                 \/\/\u56de\u50b3\u578b\u614b(int = number)\n      &#91;'string', 'number'],                     \/\/\u50b3\u5165\u53c3\u6578\u7b2c\u4e00\u500b\u70ba\u5b57\u4e32\uff0c\u7b2c\u4e8c\u500b\u662f\u70ba\u4e86C++\u56de\u50b3\u5b57\u4e32\u6307\u6a19\uff0c\u6240\u4ee5\u662fnumber\n      &#91;cmd, resultPointer]);                    \/\/\u50b3\u5165\u7684\u53c3\u6578\n  if (isValid === 1) {                          \/\/\u6536\u5230\u7684\u56de\u50b3\u6578\u503c\n    result = Module.UTF8ToString(resultPointer);\/\/\u4f7f\u7528\u5167\u5efa\u7684UTF8ToString\uff0c\u7531\u5b57\u4e32\u6307\u6a19\u7684\u4f4d\u5740\u5c07\u5b57\u4e32\u53d6\u51fa\n  }\n  Module._free(resultPointer);                  \/\/\u91cb\u653e\u8a18\u61b6\u9ad4\n  return result;\n}\n\nfunction decode(cmd) {\n  let result = \"\";\n  const resultPointer = Module._malloc(cmd.length \/ 2);\n  const isValid = Module.ccall('decode',\n      'number',\n      &#91;'string', 'number'],\n      &#91;cmd, resultPointer]);\n  if (isValid === 1) {\n    result = Module.UTF8ToString(resultPointer);\n  }\n  Module._free(resultPointer);\n  return result;\n}<\/code><\/pre>\n\n\n\n<p>\u63a5\u8457\u4f7f\u7528\u4ee5\u4e0b\u6307\u4ee4\u91cd\u65b0\u7de8\u8b6f\u4e26\u7522\u751f\u51fa encoder.js<\/p>\n\n\n\n<pre class=\"wp-block-code has-light-gray-background-color has-background has-small-font-size\"><code>emcc encode_decode.cpp -o encoder.js -s EXTRA_EXPORTED_RUNTIME_METHODS=&#91;'ccall','UTF8ToString'] -s 'EXPORTED_FUNCTIONS=&#91;\"_free\",\"_malloc\"]'\n\n1. output \u6a94\u6848\u6539\u6210encoder.js\uff0c\u7de8\u8b6f\u5668\u6703\u81ea\u52d5\u4e0d\u7522\u751fhtml\u6a94\n2. -s EXTRA_EXPORTED_RUNTIME_METHODS \u8868\u660e\u4e86\u6703\u5728js \u4e2d\u4f7f\u7528\u5230\u7684 wasm function\n    \u5176\u4e2dccall \u662f\u62ff\u4f86\u547c\u53eb C++ \u6a94\u6848\u5167function \u4f7f\u7528\u7684\n     UTF8ToString \u5247\u662f\u5c07\u56de\u50b3\u7684\u6307\u6a19\u8f49\u63db\u56dejs \u5b57\u4e32\u4f7f\u7528\n3. -s 'EXPORTED_FUNCTIONS=&#91;\"_free\",\"_malloc\"]' \u662f\u70ba\u4e86\u5728js \u4e2d\u53ef\u4ee5\u4f7f\u7528malloc \u53d6\u5f97\u8a18\u61b6\u9ad4\uff0c\u8207free \u91cb\u653e\u8a18\u61b6\u9ad4\n    \u820a\u7248\u672c\u4e0d\u9700\u8981\u7279\u5225\u6307\u5b9a\u9019\u6bb5\uff0c\u4f46\u662f\u76ee\u524d\u7684\u7248\u672c\u4e0d\u6307\u5b9a\u5247\u6703\u627e\u4e0d\u5230\u8a72function\n<\/code><\/pre>\n\n\n\n<p>\u505a\u5b8c\u4ee5\u4e0a\u52d5\u4f5c\uff0c\u5373\u53ef\u6253\u958b\u700f\u89bd\u5668\uff0c\u8f38\u5165\u201chttp:\/\/localhost:8080\/test_encoder.html\u201d<\/p>\n\n\n\n<p>\u9ede\u64ca Encode \u6642\u6703\u547c\u53eb wasm \u5167\u7684encode function \u4e26\u5c07Cmd \u4e2d\u7684\u5b57\u4e32\u8f38\u5165\u9032\u53bb\uff0c\u53d6\u5f97\u7684\u7d50\u679c\u5c07\u6703\u986f\u793a\u5728Encode \u6b04\u4f4d\u4e2d\u3002<\/p>\n\n\n\n<p>\u9ede\u64caDecode \u6642\u6703\u547c\u53ebwasm \u5167\u7684decode function \u4e26\u5c07 Encode \u4e2d\u7684\u5b57\u4e32\u8f38\u5165\u9032\u53bb\uff0c\u4e26\u5c07\u89e3\u78bc\u5f8c\u7684\u7d50\u679c\u986f\u793a\u5728Decode \u6b04\u4f4d\u4e2d\u3002<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-3.png\" alt=\"\" class=\"wp-image-352\" width=\"336\" height=\"234\" srcset=\"https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-3.png 1120w, https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-3-300x210.png 300w, https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-3-150x105.png 150w, https:\/\/blog.quantoyo.com\/wp-content\/uploads\/2023\/11\/image-3-768x538.png 768w\" sizes=\"auto, (max-width: 336px) 100vw, 336px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Emscripten \u652f\u63f4 main \u4f5c\u70ba\u8d77\u9ede\u7684\u57f7\u884c\u65b9\u5f0f\uff0c\u4f46\u5be6\u969b\u4f7f\u7528\u4e0a\u9084\u662f\u6703\u4ee5\u76f4\u63a5\u547c\u53ebfunction \u70ba\u4e3b\uff0c &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blog.quantoyo.com\/?p=349\" class=\"more-link\">\u95b1\u8b80\u5168\u6587<span class=\"screen-reader-text\">\u3008WebAssembly (wasm)\u5be6\u4f5c\u3009<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[48,47,45,46,43,44],"class_list":["post-349","post","type-post","status-publish","format-standard","hentry","category-technology","tag-c-2","tag-c","tag-html","tag-javascript","tag-wasm","tag-webassembly"],"_links":{"self":[{"href":"https:\/\/blog.quantoyo.com\/index.php?rest_route=\/wp\/v2\/posts\/349","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.quantoyo.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.quantoyo.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.quantoyo.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.quantoyo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=349"}],"version-history":[{"count":1,"href":"https:\/\/blog.quantoyo.com\/index.php?rest_route=\/wp\/v2\/posts\/349\/revisions"}],"predecessor-version":[{"id":353,"href":"https:\/\/blog.quantoyo.com\/index.php?rest_route=\/wp\/v2\/posts\/349\/revisions\/353"}],"wp:attachment":[{"href":"https:\/\/blog.quantoyo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=349"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.quantoyo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=349"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.quantoyo.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=349"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}