webassembly 02 demo code

01 EM_ASM 宏应用

emcc wasm060301.c -o wasm060301.html

#include <stdio.h>
#include <emscripten.h>

// EM_ASM_ 宏可带简单参数,但是返回的number值被截断了
void test01() {
  float sum = EM_ASM_({
    var sum = $0 + $1;
    console.log("console.log(sum):" + sum);
    return sum;
  }, 1.1, 2.2);
  printf("printf(sum(1.1, 2.2)): %f\n", sum);
}

// EM_ASM_* 宏可带简单参数,指定double类型后,不会被截断
void test02() {
  float sum = EM_ASM_DOUBLE({
    var sum = $0 + $1;
    console.log("console.log(sum):" + sum);
    return sum;
  }, 1.1, 2.2);
  printf("EM_ASM_DOUBLE printf(sum(1.1, 2.2)): %f\n", sum);
}

void test03() {
  int v = EM_ASM_INT({return 42;}, 0);
  printf("EM_ASM_INT printf %d\n", v);
}

void test04() {
  EM_ASM_({
    console.log("$0: ", $0);
    console.log("$1: ", $1);
  }, 1, 2);
}

void test05() {
  EM_ASM_({
    for(var i = 0; i < arguments.length; i++) {
      console.log("$", i, ":", arguments[i]);
    }
  }, 1, 2, 3);
}

void test06() {
  EM_ASM_({
    //var args = ([$0, $1]);
    var args = arguments;
    console.log("args: ", args);
  }, 1, 2);
}

// emcc wasm060301.c -o wasm060301.html
int main() {
  EM_ASM(console.log("你好,Emscripten!"));
  EM_ASM(console.log("hello world!"); console.log("hello world!"));
  
  EM_ASM(
    console.log("hello world!..");
    console.log("hello world!..");
  );
  
  EM_ASM(
    //console.log("hello world!...") // 没有分号运行时错误
    console.log("hello world!...")
  );
  
  test01();
  
  test02();
  
  test03();
  
  int v2 = EM_ASM_INT_V({return 42});
  printf("EM_ASM_INT_V printf %d\n", v2);
  
  int v3 = EM_ASM_INT_V(return 42);
  printf("EM_ASM_INT_V printf %d\n", v3);
  
  test04();
  
  test05();
  
  test06();
  
  return 0;
}

在这里插入图片描述

02 C++调用js

emcc -std=c++11 --js-library wasm060402_package.js -s"EXPORTED_RUNTIME_METHODS=['ptrToString', 'maybeCStringToJsString']" wasm060402.cc -o wasm060402.html

wasm060402_package.js

// package.js
// emcc -std=c++11 --js-library wasm060402_package.js -s EXPORTED_RUNTIME_METHODS="['ccall', 'getValue', 'cwrap', 'maybeCStringToJsString', 'ptrToString']" -s EXPORTED_FUNCTIONS="['_malloc', '_free', '_main']" wasm060402.cc -o wasm060402.html
mergeInto(LibraryManager.library, {
  my_run_script1: function(code, $arg) {
    eval(code);
    console.log(code);
    console.log(maybeCStringToJsString(code));
  },
  my_run_script2: function(code) {
    //eval(Pointer_stringify(code));
    //eval(UTF8ToString(code));
    eval(maybeCStringToJsString(code));
    console.log(maybeCStringToJsString(code));
    //console.log(UTF8ToString(code));
  },
  my_run_script3: function(code, $arg) {
    //eval(Pointer_stringify(code));
    //eval(UTF8ToString(code));
    eval(maybeCStringToJsString(code));
    console.log(maybeCStringToJsString(code));
    //console.log(UTF8ToString(code));
  },
  
  // 这个没搞明白
  my_run_script_string: function(code) {
    console.log(code);
    //var s = eval(ptrToString(code));
    //var s = eval(Pointer_stringify(code));
    var s = eval(UTF8ToString(code));
    var p = _my_run_script_string;
    console.log(p);
    if (!p.bufferSize || p.bufferSize < s.length()+1) {
      if (p.bufferSize) _free(p.buffer);
      p.bufferSize = lengthBytesUTF8(s)+1;
      p.buffer = _malloc(p.bufferSize);
    }
    stringToUTF8(s, p.buffer, 1024*8);
    return p.buffer;
  }
});

wasm060402.cc

// emcc -std=c++11 --js-library wasm060402_package.js -s"EXPORTED_RUNTIME_METHODS=['ptrToString', 'maybeCStringToJsString']" wasm060402.cc -o wasm060402.html
// emcc -std=c++11 --js-library wasm060402_package.js  -s"EXPORTED_RUNTIME_METHODS=['ptrToString', 'maybeCStringToJsString']" wasm060402.cc -o wasm060402.html
// https://www.cntofu.com/book/150/zh/ch2-c-js/ch2-04-data-exchange.md
// emcc -s WASM=1 -o wasm060402.html --js-library wasm060402_package.js -s "EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap', 'ptrToString']" -s ASSERTIONS=1 -O1 -O2 -O3 -std=c++11 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=1 wasm060402.cc

#include <emscripten.h>

extern "C" void EMSCRIPTEN_KEEPALIVE my_run_script1(const char* s, ...);
extern "C" void EMSCRIPTEN_KEEPALIVE my_run_script2(const char* s, ...);
extern "C" void EMSCRIPTEN_KEEPALIVE my_run_script3(const char* s, ...);

void test_error() {
  my_run_script1("console.log($arg)", 42);  // error 
  //1053
  //console.log($arg)

  my_run_script1("console.log(arguments[1])", 42); // error
  //1071
  //console.log(arguments[1])
  
  my_run_script2("console.log(arguments)", 42); // error
  // console.log(arguments)
  my_run_script2("console.log(arguments)", 1, 2, 3); // error
  // console.log(arguments)
}

void test01() {
  auto jsCode = R"(
    console.log('arg1:', getValue(arguments[1] + 0, 'i32'));
    console.log('arg2:', getValue(arguments[1] + 4, 'i32'));
    console.log('arg3:', getValue(arguments[1] + 8, 'double'));
    console.log('arg4:', maybeCStringToJsString(getValue(arguments[1] + 16, 'i64')));
    console.log('arg4:', UTF8ToString(getValue(arguments[1] + 16, 'i64')));
  )";
  my_run_script3(jsCode, 43, 2017, 3.14, "hello");
  // 输出结果
  //arg1: 43
  //arg2: 2017
  //arg3: 3.14
  //arg4: hello
  //arg4: hello
  //console.log('arg1:', getValue(arguments[1] + 0, 'i32'));
  //console.log('arg2:', getValue(arguments[1] + 4, 'i32'));
  //console.log('arg3:', getValue(arguments[1] + 8, 'double'));
  //console.log('arg4:', maybeCStringToJsString(getValue(arguments[1] + 16, 'i64')));
  //console.log('arg4:', UTF8ToString(getValue(arguments[1] + 16, 'i64')));
}

void test02() {
  auto jsCode = R"(
    console.log('arg1:', HEAP32[(arguments[1] + 0) / 4]);
    console.log('arg2:', HEAP32[(arguments[1] + 4) / 4]);
    console.log('arg3:', HEAP32[(arguments[1] + 8) / 4]);
    console.log('arg4:', maybeCStringToJsString(HEAP32[(arguments[1] + 12) / 4]));
  )";
  my_run_script2(jsCode, 1, 2, 3, "hello");
  //arg1: 1
  //arg2: 2
  //arg3: 3
  //arg4: hello
  //
  //console.log('arg1:', HEAP32[(arguments[1] + 0) / 4]);
  //console.log('arg2:', HEAP32[(arguments[1] + 4) / 4]);
  //console.log('arg3:', HEAP32[(arguments[1] + 8) / 4]);
  //console.log('arg4:', maybeCStringToJsString(HEAP32[(arguments[1] + 12) / 4]));
}

void test03() {
  auto jsCode = R"(
    for(let i = 0; i < arguments.length; i++) {
      console.log("arg" + i.toString() + ":" + maybeCStringToJsString(HEAP32[(arguments[1] + 4*i) >> 2]));
    }
  )";  
  my_run_script2(jsCode, "hello", "world", 2, 3);
  //arg0:hello
  //arg1:world
  //for(let i = 0; i < arguments.length; i++) {
  //  console.log("arg" + i.toString() + ":" + maybeCStringToJsString(HEAP32[(arguments[1] + 4*i) >> 2]));
  //}
}

void test04() {
  auto jsCode = R"(
    console.log('arg1:', getValue(arguments[1] + 8*0, 'double'));
    console.log('arg2:', getValue(arguments[1] + 8*1, 'double'));
    console.log('arg3:', getValue(arguments[1] + 8*2, 'double'));
  )";
  my_run_script2(jsCode, 1.1f, 2.2f, 3.3f);
  //arg1: 1.100000023841858
  //arg2: 2.200000047683716
  //arg3: 3.299999952316284
  //console.log('arg1:', getValue(arguments[1] + 8*0, 'double'));
  //console.log('arg2:', getValue(arguments[1] + 8*1, 'double'));
  //console.log('arg3:', getValue(arguments[1] + 8*2, 'double'));
}

void test05() {
  auto jsCode = R"(
    console.log('arg1:', maybeCStringToJsString(getValue(arguments[1] + 0, 'i32')));
    console.log('arg2:', getValue(arguments[1] + 4, 'i32'));
    console.log('arg3:', getValue(arguments[1] + 8, 'double'));
    console.log('arg4:', getValue(arguments[1] + 16, 'i32'));
    
  )";
  my_run_script2(jsCode, "hello", 43, 3.14f, 2022);
  //arg1: hello
  //arg2: 43
  //arg3: 3.140000104904175
  //arg4: 2022
  //console.log('arg1:', maybeCStringToJsString(getValue(arguments[1] + 0, 'i32')));
  //console.log('arg2:', getValue(arguments[1] + 4, 'i32'));
  //console.log('arg3:', getValue(arguments[1] + 8, 'double'));
  //console.log('arg4:', getValue(arguments[1] + 16, 'i32'));
}

#include <string>
#include <stdlib.h>
extern "C" const char* my_run_script_string(const char* s, ...);
void test06() {
  printf("###############\n");
  std::string s0 = my_run_script_string("console.log('hello')");
  std::string s1 = my_run_script_string("console.log('world')");
  printf("%s, %s\n", s0.c_str(), s1.c_str());
}

int main() {
  test_error();
  test01();
  test02();
  test03();
  test04();
  test05();
  //test06(); // 这个没搞明白
  
  return 0;
}

03 js 调用 c++

emcc -std=c++11 -s EXPORTED_FUNCTIONS="['_test01', '_mymain', '_main']" wasm060501.cc -o wasm060501.html

// wasm060501.cc
//#include "wasm060501.h"
#include <stdio.h>
#include <emscripten.h>
#if defined(__cplusplus)
#define CAPI_EXPORT(rettype) extern "C" rettype
#else
#define CAPI_EXPORT(rettype) rettype
#endif

// emcc -std=c++11 -s EXPORTED_RUNTIME_METHODS="['ccall', 'getValue', 'cwrap', 'maybeCStringToJsString', 'ptrToString']" -s EXPORTED_FUNCTIONS="['_mymain']" wasm060501.cc -o wasm060501.html
// emcc -std=c++11 -s EXPORTED_FUNCTIONS="['_test01', '_mymain', '_main']"  wasm060501.cc -o wasm060501.html
CAPI_EXPORT(int) mymain() {
  printf("hello, mymain\n");
  return 0;
}

extern "C" int test01() {
  printf("test01\n");
  return 43;
}


int preMain = emscripten_run_script_int(R"==(
  // 禁止main()函数的自动运行
  Module.noInitialRun = true;
  showdRunNow = false;
  console.log("== js call myamin ==");
  // 调用mymain()函数
  let ret = Module._mymain();
  console.log("myamin()=" + ret);
  console.log("\n js call test01 \n");
  ret = Module._test01();
  console.log("test01()=" + ret);
)==");

void test02() {
  printf("test02\n");
}

int test03() {
  printf("test03\n");
  return 3;
}

int main() {
  printf("\nhello world\n");
  test02();
  test03();
  mymain();
  //Module._test01();
  return 0;
}

在这里插入图片描述

04 消息机制

emcc -std=c++11 wasm060603.cc -o wasm060603.html

wasm060603.cc

#include <stdio.h>
#include <SDL.h>
#include <emscripten.h>

// emcc -std=c++11 wasm060603.cc -o wasm060603.html

SDL_Surface* screen = NULL;

void do_web_frame() {
  SDL_Event event;
  while(SDL_PollEvent(&event)) {
    switch(event.type) {
      case SDL_QUIT:
        break;
      
      case SDL_MOUSEMOTION:
        printf("mouse(x, y): (%d, %d)\n", event.button.x, event.button.y);
        fflush(stdout);
        break;
    }
  }
}

int main() {
  SDL_Init(SDL_INIT_VIDEO);
  screen = SDL_SetVideoMode(1024, 768, 32, SDL_ANYFORMAT);
  
  // 在 do_web_frame 中通过SDL_PollEvent获取输入消息
  emscripten_set_main_loop(do_web_frame, 0, 0);
  return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值