まず、オープン ソース ライブラリを 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
**ブラウザの結果**