参考文档:www.cntofu.com/book/150/in…
记录自己写的几个测试的函数,用来实现c++与js交互。主要包括指针类型的数据的传递。
main.cpp
#ifndef EM_PORT_API
# if defined(__EMSCRIPTEN__)
# include <emscripten.h>
# include <emscripten/val.h>
# include <emscripten/bind.h>
using namespace emscripten;
# if defined(__cplusplus)
# define EM_PORT_API(rettype) extern "C" rettype EMSCRIPTEN_KEEPALIVE
# else
# define EM_PORT_API(rettype) rettype EMSCRIPTEN_KEEPALIVE
# endif
# else
# if defined(__cplusplus)
# define EM_PORT_API(rettype) extern "C" rettype
# else
# define EM_PORT_API(rettype) rettype
# endif
# endif
#endif
#include <iostream>
#include <string.h>
#include "Student.h"
/**
* recv int,return void
*/
EM_PORT_API(void) test(int a) {
cout << "test called, a=" << a << endl;
}
/**
* recv byte*, return int
*/
EM_PORT_API(int) sum(uint8_t* ptr, int count) {
int total = 0, temp;
for (int i = 0; i < count; i++){
memcpy(&temp, ptr + i * 4, 4);
cout << "[" << i << "], num = " << temp << endl;
total += temp;
}
return total;
}
/**
* recv int*,return int
*/
EM_PORT_API(int) sumInt(int* ptr, int count) {
int total = 0;
for (int i = 0; i < count; i++){
cout << "[" << i << "], num = " << ptr[i] << endl;
total += ptr[i];
}
return total;
}
/**
* recv float*,return float
*/
EM_PORT_API(float) sumFloat(float* ptr, int count) {
float total = 0;
for (int i = 0; i < count; i++){
cout << "[" << i << "], num = " << ptr[i] << endl;
total += ptr[i];
}
return total;
}
/**
* recv float*,return float*
*/
EM_PORT_API(float*) getFloats(float* ptr, int count) {
float* total = new float[count];
for (int i = 0; i < count; i++){
cout << "[" << i << "], num = " << ptr[i] << endl;
total[i] = ptr[i] + 1;
cout << "[" << i << "], num + 1= " << total[i] << endl;
}
return total;
}
/**
* recv float*, js callback
*/
EM_PORT_API(void) call(float* ptr, int count) {
float* total = new float[count];
for (int i = 0; i < count; i++){
cout << "[" << i << "], num = " << ptr[i] << endl;
total[i] = ptr[i] + 1;
}
for (int i = 0; i < 2; ++i) {
EM_ASM_(
{
callback_btn6($0);
},
total
);
}
}
/**
* recv int*,return float*
*/
EM_PORT_API(float*) merge(int *ptr, int count)
{
float* total = new float[count + 3];
total[0] = 0.1f;
total[1] = 0.2f;
total[2] = 0.3f;
memcpy(total+3,ptr,sizeof(int) * count);
return total;
}
/**
* recv float*,return void
*/
EM_PORT_API(void) cpp_recv(float *ptr, int count)
{
int* tmp = new int[count - 3];
for (int i = 0; i < 3; ++i) {
cout << *(ptr+i)<< endl;
}
tmp = (int *)(ptr + 3);
for (int i = 0; i < count - 3; ++i) {
cout << *(tmp+i)<< endl;
}
}
Makefile
TAG=main.js main.wasm
OBJ=Student.o main.o
CC:=emcc
RM:=rm -rf
$(TAG):$(OBJ)
$(CC) -std=c++11 $^ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap']" -o $@
%.o:%.cpp
$(CC) -std=c++11 -c $^ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap']" -o $@
.PHONY: clean cleanall
clean:
$(RM) $(OBJ)
cleanall:
$(RM) $(OBJ) $(TAG)
make完成之后会生成main.js和main.wasm。就成功了
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn1">call</button>
<br>
<button id="btn2">pass int array</button>
<br>
<button id="btn3">pass int array</button>
<br>
<button id="btn4">pass float array</button>
<br>
<button id="btn5">pass float array return float array</button>
<br>
<button id="btn6">c++ callback js return float array</button>
<br>
<button id="btn7">merge float* and int*, c++ return float*</button>
<br>
<button id="btn8">get data from btn7,trans data to float*</button>
<script>
Module = {};
function callback_btn6(data) {
alert(Module.HEAPF32[data >> 2]);
alert(Module.HEAPF32[(data + 4) >> 2]);
alert(Module.HEAPF32[(data + 8) >> 2]);
alert(Module.HEAPF32[(data + 12) >> 2]);
alert(Module.HEAPF32[(data + 16) >> 2]);
}
var str_pass = "";
Module.onRuntimeInitialized = function() {
var btn1 = document.getElementById('btn1');
btn1.onclick = function() {
Module.ccall('test', 'null', ['number'], [10]);
}
var btn2 = document.getElementById('btn2');
btn2.onclick = function() {
var count = 50;
var buf = new ArrayBuffer(count * 4);
var i8 = new Uint8Array(buf);
var i32 = new Int32Array(buf);
for (var i = 0; i < count; i++){
i8[i] = i + 1;
}
result = Module.ccall('sum', 'number', ['array', 'number'], [i8, count]);
alert(result);
}
var btn3 = document.getElementById('btn3');
btn3.onclick = function() {
var count = 5;
var ptr = Module._malloc(4 * count);
for (var i = 0; i < count; i++){
Module.HEAP32[ptr / 4 + i] = i + 1;
}
console.log(Module._sumInt(ptr, count));
Module._free(ptr);
}
var btn4 = document.getElementById('btn4');
btn4.onclick = function() {
var count = 5;
var ptr = Module._malloc(4 * count);
for (var i = 0; i < count; i++){
Module.HEAPF32[ptr / 4 + i] = i + 1.1;
}
alert(Module._sumFloat(ptr, count));
Module._free(ptr);
}
var btn5 = document.getElementById('btn5');
btn5.onclick = function() {
var count = 5;
var ptr = Module._malloc(4 * count);
for (var i = 0; i < count; i++){
Module.HEAPF32[ptr / 4 + i] = i + 1.1;
}
var float_ptr = Module._getFloats(ptr, count);
// alert(int_ptr);
alert(Module.HEAPF32[float_ptr >> 2]);
alert(Module.HEAPF32[(float_ptr + 4) >> 2]);
alert(Module.HEAPF32[(float_ptr + 8) >> 2]);
alert(Module.HEAPF32[(float_ptr + 12) >> 2]);
alert(Module.HEAPF32[(float_ptr + 16) >> 2]);
// alert(Module.HEAP32[int_ptr >> 2]);
Module._free(ptr);
Module._free(float_ptr);
}
var btn6 = document.getElementById('btn6');
btn6.onclick = function() {
var count = 5;
var ptr = Module._malloc(4 * count);
for (var i = 0; i < count; i++){
Module.HEAPF32[ptr / 4 + i] = i + 1.1;
}
Module._call(ptr, count)
//alert(Module._sumFloat(ptr, count));
Module._free(ptr);
}
var btn7 = document.getElementById('btn7');
btn7.onclick = function() {
var count = 5;
var ptr = Module._malloc(4 * count);
for (var i = 0; i < count; i++){
Module.HEAP32[ptr / 4 + i] = i + 1;
}
var res = Module._merge(ptr, count);
var str = '';
for (var i = 0; i < 3; i++){
str += Module.HEAPF32[(res >> 2) + i];
str += '|';
}
for (var i = 3; i < 3 + count; i++){
str += Module.HEAP32[(res >> 2) + i];
str += '|';
}
console.log(str);
str_pass = str;
//alert(Module._sumFloat(ptr, count));
Module._free(ptr);
Module._free(res);
var array = str.split("|");
// for (var j = 0; j<array.length; j++) {
// alert(array[j]);
// }
}
var btn8 = document.getElementById('btn8');
btn8.onclick = function() {
var array = str_pass.split("|");
var ptr = Module._malloc(4 * (array.length -1));
for (var j = 0; j<3; j++) {
Module.HEAPF32[ptr / 4 + j] = array[j];
}
for (var j = 3; j<array.length-1; j++) {
console.log(">>>"+array[j]);
Module.HEAP32[ptr / 4 + j] = array[j];
}
Module._cpp_recv(ptr,array.length -1);
Module._free(ptr);
}
}
</script>
<script src="main.js"></script>
</body>
</html>