Web程序集:使用带有c ++库的emscripten

时间:2017-01-13 01:33:12

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

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

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

在这两次通话之后,我的/usr/local/<name of open source>/lib中的.a库以及/usr/local/<name of open source>/include

中的头文件

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

问题是:如何为此cpp文件创建html文件? 这种文件的名称是&#34; test.cpp&#34; 我尝试了这个命令,但它导致了许多未解决的符号&#34;

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

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

现在回到你问题的另一部分,emscripten将只为那些你公开&#34;的C ++函数创建一个JS函数。 (显然,这些公开函数调用的函数也将被编译,其余部分被剥离)。

可以找到关于实现这一目标的小教程here

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

答案 2 :(得分:0)

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

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

您需要在编译命令中添加选项-l<name of your library>,以指定您希望将lib与您的程序链接。

答案 3 :(得分:0)

首先,您的开源库需要使用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

**浏览器中的结果** enter image description here