我计划将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没有显示我希望它显示的内容。
你能帮帮我吗?
答案 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