2

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

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

在这两个电话之后,我的 .a 库/usr/local/<name of open source>/lib以及我的头文件/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 没有显示我期望它显示的内容。

你能帮我么?

控制台中未解决的符号警告

4

4 回答 4

1

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

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

可以在此处找到有关实现此目的的小教程

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

于 2017-01-23T15:13:25.727 回答
0

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

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

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

于 2017-01-25T12:26:24.397 回答
0

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

于 2017-01-15T07:38:04.483 回答
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++ - 你好.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

** 浏览器中的结果** 在此处输入图像描述

于 2020-03-05T00:46:04.633 回答