Emscripten运行main和Emscripten_set_main_loop

一、main()函数与生命周期

对于Emscripten来说,main()函数既不是必需的,也不控制运行时生命周期。

1、test.c

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

//extern "C" {

EMSCRIPTEN_KEEPALIVE	
int show_answer()
{
	return 42;
}

int main()
{
	printf("hello world\n");
	return 1;
}
//}

2、test.html

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
    <title>Web--Test</title>
    <style>

    </style>
</head>
<body>

<div class="button_box">
    <div class="items">
		<button type="button" onClick="start()">start</button>
		<button type="button" onClick="stop()">stop</button>
    </div>
</div>

<script async type="text/javascript" src="test.js"></script>
 <script>
    function start(){
	    //Module._malloc100M();
		let ans = Module._show_answer();
		console.log("ans:"+ans);
	}
 </script>   
</body>
</html>

二、消息循环

1、C++中的消息循环

int main()
{
    while(1){
        msg_loop();
    }
    return 0;
}

网页中的JavaScript脚本是单线程运行的。如果一个带有消息循环的C/C++程序不加处理,直接使用Emscripten编译后导入网页中运行,则消息循环不退出,并堵塞页面程序的运行,导致DOM无法更新,使整个页面失去响应。

为此,Emscripten提供了一组函数用于消息循环的模拟及调度执行。

2、emscripten_set_main_loop()

该函数用于创建主消息循环,在消息循环建立后按照设定的频率调用指定的回调函数。

void emscripten_set_main_loop(em_callback_func func,int fps,int simulate_infinite_loop)

func:消息处理回调函数。
fps:消息循环的执行帧率。如果该参数小于等于0,则使用页面的requestAnimationFrame机制调用消息处理函数。该机制可以确保页面刷新率与显示器刷新率对等。(对于需要执行图形渲染任务的程序,使用该机制可以得到平滑的渲染速度)。
simulate_infinite_loop:是否模拟“无限循环”。当设为1时,emscripten_set_main_loop()函数的后续代码不执行,main()函数栈未销毁。无论是0还是1,消息处理函数都会按照设定的帧率无限执行。

3、test.c

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

//extern "C" {

EMSCRIPTEN_KEEPALIVE	
void msg_loop()
{
	static int count= 0;
	if(count%60 ==0)
	{
		printf("count:%d\n",count);
	}
	count++;
}
EMSCRIPTEN_KEEPALIVE	
void pause_main_loop()
{
	emscripten_pause_main_loop();
	printf("pause main loop\n");
}
EMSCRIPTEN_KEEPALIVE	
void resume_main_loop()
{
	emscripten_resume_main_loop();
	printf("resume main loop\n");
}
EMSCRIPTEN_KEEPALIVE	
void cancel_main_loop()
{
	emscripten_cancel_main_loop();
	printf("cancel main loop\n");
}
int main()
{
	printf("main loop start\n");
	emscripten_set_main_loop(msg_loop,0,1);
	printf("main loop end\n");
	return 1;
}
//}

4、test.html

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
    <title>Web--Test</title>
    <style>

    </style>
</head>
<body>

<div class="button_box">
    <div class="items">
		<button id=pause onClick=pause()>pause</button>
		<button id=resume onClick=resume()>resume</button>
		<button id=cancel onClick=cancel()>cancel</button>
    </div>
</div>

<script async type="text/javascript" src="test.js"></script>
 <script>
	function pause(){
		Module._pause_main_loop();
	}
	function resume(){
		Module._resume_main_loop();
	}
	function cancel(){
		Module._cancel_main_loop();
	}
	Module={};
	Module.onRuntimeInitiallized =function(){
	    document.getElementById("pause").disabled=false;
		document.getElementById("resume").disabled=false;
		document.getElementById("cancel").disabled=false;
	
	}
 </script>   
</body>
</html>

Emscripten提供的消息循环函数对C/C++代码来说是侵入式的,因此在工程中应尽可能避免使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值