【问题标题】:Web assembly: using emscripten with c++ libraryWeb 程序集:将 emscripten 与 c++ 库一起使用
【发布时间】:2017-01-13 01:33:12
【问题描述】:

我正计划将 c++ 库用于 Web 应用程序,而 Web 程序集似乎是一个很好的工具。我正在使用 emscripten 进行编译。

我得到了这个开源 c++ 库的源代码,并使用 emmake makeemmake make install

在这两个电话之后,我的/usr/local/<name of open source>/lib 中有.a 库,/usr/local/<name of open source>/include 中有头文件

我还有一个使用这个开源库的示例 cpp 代码。

问题是:如何为这个 cpp 文件创建一个 html 文件? 此类文件的名称是“test.cpp” 我试过这个命令,但它会导致很多“未解析的符号”

em++ -I/usr/local/<name of open source>/include -L/usr/local/<name of open source>/lib test.cpp -s WASM=1 -o final.html

然后我调用 emrun 在我的本地运行 Web 服务器,但 final.html 没有显示我期望它显示的内容。

你能帮帮我吗?

unresolved symbol warnings in the console

【问题讨论】:

  • 这似乎不是 WebAssembly 特有的。您能按照 Emscripten 的常规 asm.js 说明进行操作,看看是否遇到相同的错误吗?如果是这样,这些错误是什么?此外,你能使用/usr/local吗? Emscripten 有自己的 C 和 C++ 标准库。
  • 您好,它不是一个标准库,我正在尝试使用它是一个由开发人员开发的开源项目,用于为科学研究进行一些密集的计算。另外,我尝试按照 Emscripten 的常规 asm.js 说明进行操作,但它似乎也不起作用。
  • JF Bastien:您提到“Emscripten 有自己的 C 和 C++ 标准库”。你能扩展一下吗? Tnx

标签: javascript c++ emscripten asm.js webassembly


【解决方案1】:

警告(实际上是错误)表明您没有通过 emscripten 编译包含库的 cpp 文件。除了文件 test.cpp,您还需要将项目所需的每个文件提供给 em++ 命令。 阅读here了解更多信息。

现在谈到您问题的另一部分,emscripten 只会为您“公开”的那些 C++ 函数创建一个 JS 函数。 (显然这些暴露函数调用的函数也会被编译,其余的被剥离)。

可以在here找到实现此功能的小教程

一旦你的函数被暴露出来,你就可以从你自己的 JS 代码中调用它们(例如:将它们绑定到 JS 事件上)

【讨论】:

  • 只是想指出你是个天才。我不知道为什么我认为我可以添加 .a (lib) 和包含,这一切都会像魔术一样工作。
【解决方案2】:

看起来您的库可能具有未满足的依赖项(未解析的符号)。 emscripten 构建是交叉构建,这意味着它不能使用您安装的系统库;相反,您必须使用 emscripten 编译器构建所有依赖项。 Emscripten 有一个不幸的行为,即未解析的符号是警告(其他链接器认为这些是错误),但如果你有它们,你的程序不太可能工作。

【讨论】:

    【解决方案3】:

    由于各种原因,Emscripten 不会将未解析的符号视为编译错误。

    在编译项目时,还需要链接生成的.a库。 您使用的 -I-L 选项指定了在哪里查找要与程序链接的库,但它没有指定要链接的库。

    您需要将选项-l&lt;name of your library&gt; 添加到您的编译命令中,以指定您希望该库与您的程序链接。

    【讨论】:

      【解决方案4】:

      首先你的开源库需要用 LLVM 位码编译。

      在我的示例中,我使用 Botan 库。它以前是在 LLVM 位码中编译的。

      libbotan-2.a 在 LLVM 位码中。

      我的文件树

      HelloProject:.
      │   hello.cpp
      │   hello.js
      │   hello.wasm
      │   test.html
      │
      ├───include
      │   └───botan-2
      │       └───botan
      │               adler32.h
      │               aead.h
      │               aes.h
      │               alg_id.h
      │               argon2.h
      │               aria.h
      │               asn1_alt_name.h
      │               asn1_attribute.h
      │               asn1_obj.h
      │               asn1_oid.h
      │               asn1_print.h
      │               asn1_str.h
      │               asn1_time.h
      │               assert.h
      │               atomic.h
      │               auto_rng.h
      │               base32.h
      │               base58.h
      │               base64.h
      │               basefilt.h
      │               bcrypt.h
      │               bcrypt_pbkdf.h
      │               ber_dec.h
      │               bigint.h
      │               blake2b.h
      │               blinding.h
      │               block_cipher.h
      │               blowfish.h
      │               botan.h
      │               bswap.h
      │               buf_comp.h
      │               buf_filt.h
      │               build.h
      │               calendar.h
      │               camellia.h
      │               cascade.h
      │               cast128.h
      │               cast256.h
      │               cbc.h
      │               cbc_mac.h
      │               ccm.h
      │               cecpq1.h
      │               certstor.h
      │               certstor_flatfile.h
      │               certstor_sql.h
      │               certstor_system.h
      │               cert_status.h
      │               cfb.h
      │               chacha.h
      │               chacha20poly1305.h
      │               chacha_rng.h
      │               charset.h
      │               cipher_filter.h
      │               cipher_mode.h
      │               cmac.h
      │               comb4p.h
      │               compiler.h
      │               comp_filter.h
      │               cpuid.h
      │               crc24.h
      │               crc32.h
      │               credentials_manager.h
      │               crl_ent.h
      │               cryptobox.h
      │               ctr.h
      │               curve25519.h
      │               curve_gfp.h
      │               curve_nistp.h
      │               database.h
      │               datastor.h
      │               data_snk.h
      │               data_src.h
      │               der_enc.h
      │               des.h
      │               desx.h
      │               dh.h
      │               divide.h
      │               dlies.h
      │               dl_algo.h
      │               dl_group.h
      │               dsa.h
      │               dyn_load.h
      │               eax.h
      │               ecc_key.h
      │               ecdh.h
      │               ecdsa.h
      │               ecgdsa.h
      │               ecies.h
      │               eckcdsa.h
      │               ec_group.h
      │               ed25519.h
      │               elgamal.h
      │               eme.h
      │               eme_pkcs.h
      │               eme_raw.h
      │               emsa.h
      │               emsa1.h
      │               emsa_pkcs1.h
      │               emsa_raw.h
      │               emsa_x931.h
      │               entropy_src.h
      │               exceptn.h
      │               fd_unix.h
      │               ffi.h
      │               filter.h
      │               filters.h
      │               fpe_fe1.h
      │               gcm.h
      │               gf2m_small_m.h
      │               ghash.h
      │               gmac.h
      │               gost_28147.h
      │               gost_3410.h
      │               gost_3411.h
      │               hash.h
      │               hash_id.h
      │               hex.h
      │               hkdf.h
      │               hmac.h
      │               hmac_drbg.h
      │               hotp.h
      │               http_util.h
      │               idea.h
      │               init.h
      │               iso9796.h
      │               kasumi.h
      │               kdf.h
      │               kdf1.h
      │               kdf1_iso18033.h
      │               kdf2.h
      │               keccak.h
      │               keypair.h
      │               key_constraint.h
      │               key_filt.h
      │               key_spec.h
      │               lion.h
      │               loadstor.h
      │               locking_allocator.h
      │               lookup.h
      │               mac.h
      │               mceies.h
      │               mceliece.h
      │               md4.h
      │               md5.h
      │               mdx_hash.h
      │               mem_ops.h
      │               mgf1.h
      │               misty1.h
      │               mode_pad.h
      │               monty.h
      │               mul128.h
      │               mutex.h
      │               name_constraint.h
      │               newhope.h
      │               nist_keywrap.h
      │               noekeon.h
      │               numthry.h
      │               oaep.h
      │               ocb.h
      │               ocsp.h
      │               ocsp_types.h
      │               ofb.h
      │               oids.h
      │               p11.h
      │               p11_ecc_key.h
      │               p11_ecdh.h
      │               p11_ecdsa.h
      │               p11_module.h
      │               p11_object.h
      │               p11_randomgenerator.h
      │               p11_rsa.h
      │               p11_session.h
      │               p11_slot.h
      │               p11_x509.h
      │               package.h
      │               parsing.h
      │               par_hash.h
      │               passhash9.h
      │               pbes2.h
      │               pbkdf.h
      │               pbkdf1.h
      │               pbkdf2.h
      │               pem.h
      │               pgp_s2k.h
      │               pipe.h
      │               pkcs10.h
      │               pkcs11.h
      │               pkcs11f.h
      │               pkcs11t.h
      │               pkcs8.h
      │               pk_algs.h
      │               pk_keys.h
      │               pk_ops.h
      │               pk_ops_fwd.h
      │               point_gfp.h
      │               poly1305.h
      │               polyn_gf2m.h
      │               pow_mod.h
      │               prf_tls.h
      │               prf_x942.h
      │               psk_db.h
      │               psk_db_sql.h
      │               pssr.h
      │               pubkey.h
      │               pwdhash.h
      │               rc4.h
      │               reducer.h
      │               rfc3394.h
      │               rfc6979.h
      │               rmd160.h
      │               rng.h
      │               rotate.h
      │               rsa.h
      │               salsa20.h
      │               scan_name.h
      │               scrypt.h
      │               secmem.h
      │               secqueue.h
      │               seed.h
      │               serpent.h
      │               sha160.h
      │               sha2_32.h
      │               sha2_64.h
      │               sha3.h
      │               shacal2.h
      │               shake.h
      │               shake_cipher.h
      │               siphash.h
      │               siv.h
      │               skein_512.h
      │               sm2.h
      │               sm2_enc.h
      │               sm3.h
      │               sm4.h
      │               sodium.h
      │               sp800_108.h
      │               sp800_56a.h
      │               sp800_56c.h
      │               srp6.h
      │               stateful_rng.h
      │               stl_compatibility.h
      │               stream_cipher.h
      │               stream_mode.h
      │               streebog.h
      │               symkey.h
      │               sym_algo.h
      │               system_rng.h
      │               threefish.h
      │               threefish_512.h
      │               tiger.h
      │               tls_alert.h
      │               tls_algos.h
      │               tls_blocking.h
      │               tls_callbacks.h
      │               tls_channel.h
      │               tls_ciphersuite.h
      │               tls_client.h
      │               tls_exceptn.h
      │               tls_extensions.h
      │               tls_handshake_msg.h
      │               tls_magic.h
      │               tls_messages.h
      │               tls_policy.h
      │               tls_server.h
      │               tls_server_info.h
      │               tls_session.h
      │               tls_session_manager.h
      │               tls_session_manager_sql.h
      │               tls_version.h
      │               totp.h
      │               tss.h
      │               twofish.h
      │               types.h
      │               uuid.h
      │               version.h
      │               whrlpool.h
      │               workfactor.h
      │               x509cert.h
      │               x509path.h
      │               x509self.h
      │               x509_ca.h
      │               x509_crl.h
      │               x509_dn.h
      │               x509_ext.h
      │               x509_key.h
      │               x509_obj.h
      │               x919_mac.h
      │               xmss.h
      │               xmss_address.h
      │               xmss_common_ops.h
      │               xmss_hash.h
      │               xmss_index_registry.h
      │               xmss_key_pair.h
      │               xmss_parameters.h
      │               xmss_privatekey.h
      │               xmss_publickey.h
      │               xmss_tools.h
      │               xmss_wots_parameters.h
      │               xmss_wots_privatekey.h
      │               xmss_wots_publickey.h
      │               xtea.h
      │               xts.h
      │
      └───libs
          └───Botan
                  libbotan-2.a
      

      编译
      运行命令

      em++ hello.cpp libs/botan/libbotan-2.a -s WASM=1 -o hello.js -std=c++17 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall']" -O3 -I include/botan-2
      

      C++ - hello.cpp

      #include <iostream>
      #include <vector>
      #include <emscripten.h>
      #include "botan/sha2_64.h"
      #include "botan/base64.h"
      #define EXTERNC extern "C"
      
      int main(int argc, char ** argv) {
          std::cout<<u8"Hello World from main\n";
      }
      
      EXTERNC const char * EMSCRIPTEN_KEEPALIVE  GetSha512Hash(const char* data) {
          std::cout<< "Received from JS: "<<data << std::endl;
          Botan::SHA_512 sha;
          std::vector<uint8_t> buffer(data, data + strlen(data));
          //std::fread(&buffer[0], 1, buffer.size(), pFile);
          return Botan::base64_encode(sha.process(buffer)).c_str();
      }
      

      HTML/JS - Test.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
      </head>
      <body>
          <script type="text/javascript" src="hello.js"></script>
          <button onclick="native()">click</button>
      
          <script type='text/javascript'>
      
            function native() {
              var result = Module.ccall(
                          'GetSha512Hash',    // name of C function 
                          "string",   // return type
                          ["string"], // argument types
                          ["Joma"]    // arguments
                      );
              console.log("Returned from CPP: " + result);
            }
      
          </script>
      
      </body>
      </html>
      

      在浏览器中测试 WASM
      运行命令

      emrun --browser "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" .\test.html
      

      ** 浏览器中的结果**

      【讨论】:

        猜你喜欢
        • 2022-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多