簡體   English   中英

Web 程序集:將 emscripten 與 C++ 庫一起使用

[英]Web assembly: using emscripten with c++ library

我計划為 Web 應用程序使用 C++ 庫,而 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 沒有顯示我期望它顯示的內容。

你能幫我么?

控制台中未解決的符號警告

警告(實際上是錯誤)表明您沒有通過 emscripten 編譯包含庫的 cpp 文件。 除了文件 test.cpp,您還需要向 em++ 命令提供項目所需的每個文件。 閱讀此處了解更多信息。

現在來到您問題的另一部分,emscripten 只會為您“公開”的那些 C++ 函數創建一個 JS 函數。 (顯然這些暴露的函數調用的函數也會被編譯,其余的被剝離)。

可以在此處找到有關實現此目標的小教程

一旦你的函數被公開,你就可以從你自己的 JS 代碼中調用它們(例如:在 JS 事件上綁定它們)

看起來您的庫可能具有未滿足的依賴項(未解析的符號)。 emscripten 構建是交叉構建,這意味着它不能使用您安裝的系統庫; 相反,您必須使用 emscripten 編譯器構建所有依賴項。 Emscripten 有一個不幸的行為,即未解析的符號是警告(其他鏈接器認為這些是錯誤),但如果你有它們,你的程序就不太可能工作。

由於各種原因,Emscripten 不會將未解析的符號視為編譯錯誤。

編譯項目時,還需要鏈接生成的.a庫。 您使用的-I-L選項指定在何處查找要與程序鏈接的庫,但未指定要鏈接哪些庫。

您需要在編譯命令中添加選項-l<name of your library>以指定您希望將 lib 與您的程序鏈接。

首先你的開源庫需要在 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

** 結果在瀏覽器中** 在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM