cheerp 数据类型包装

这个文章主要描述在cheerp环境下, js和c++侧数据类型的转换和包装内容。

1 基础数据类型

首先我们知道javascript是弱类型的脚本语言,开发者在开发的时候不必关注数据的类型和边界,而c++是静态编程语言, 在编译阶段就需要确定类型,在编译器处理的时候可以获得更好的优化。

我们都知道js所拥有的数值类型,(int,uint,float,double)默认不区分都是double类型存储,这点和lua很相似。

在一般堆栈机下,如果使用函数调用会有大量的push,pop指令来获取传递的参数,还要在内部进行根据类型包装成可识别的类型。

cheerp的内存模型是平坦的,目标如果不是wasm的话, 是和js一致的,可以直接调用(翻译成javascript,不需要push,pop这种指令)。

在cheerp环境下如果交织javascript和c++代码, cheerp会通过位移移除来替我们处理类型, 比如int类型,用js的Number左移两位来标识。我们可以不关心这些基础数据的转换。

2复合数据类型

如果是js模式,cheerp会将js对象转换成struct,或者是class类的映射,默认不推荐使用动态结构。 首先要在cheerp侧拥有对应的结构定义,才能获取和写入属性。 从js侧生成库给c++使用: 比如公开一个函数到c++

function window_base64_encode(s) {
		return window.btoa(s);
  }

我们在c++里定义

String * window_base64_encode(String *);

cheerp 会自动给我们生成函数调用参数的原型,并切映射到js侧. 如果是传输的对象我们可以使用Object* 来标识js侧的对象。

Object * window_getData(String * );

如果是wasm模式,cheerp会严格遵守c++标准,对数据进行转换。 如果要传输复合类型的数据,比如说对象那么我们需要用struct对基础数据进行包装.而不是直接使基础类型.

struct Sub {
	int age ;
};

struct Data {
	char hellow [20];
	int age ;
	struct Sub c;
};

等同于{age:20, c:{age:21},hellow:"cheerp"}

从c++调用js:

//JSExportAPI::test();
	uint8 Indata[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	for(char i = 0; i < 16; i++) {
		Indata[i] = i; ///用例
	}
	
	JSExportAPI::myJsSayHello(Indata); ///wasm调用js
	for(char i = 0; i < 16; i++) {
		std::cout  << (*Indata+i)<< endl; //结果
	}

从js调用c++

int myCppSayHello(Data a) {
	cout << "hellow i am from cpp " <<endl;
	cout  <<"hellow="<< a.hellow <<endl;
	cout  <<"age="<< a.age <<endl;
	cout  <<"sub.age="<< a.c.age <<endl;
	return 0;
}

class [[cheerp::genericjs]] JSExportAPI {
	public:
	JSExportAPI() {
	}
	
	static void myJsSayHello (uint8 * buffer) {
		Uint8Array * t = (Uint8Array *)cheerp::MakeArrayBufferView(buffer);
		auto array = cheerp::makeArrayRef(t);

		for( int i = 0 ; i < array->get_length(); i++ ) {
			array[i] = array[i] + 100 ;
			*(buffer+i) = array[i];
		}
		
		struct Data d ;
		d.age = 20;
		d.c   = {21};
		memcpy(d.hellow ,"cheerp", 7);
		myCppSayHello(d);///js调用wasm
	}
};

[[cheerp::genericjs]] 字段是生成js模式的代码。

无论是js到c++还是c++到js, cheerp转换的开销比一般的(ffi)的技术开销要小很多。类型包装也是他性能优化的基础方式之一。

转载于:https://my.oschina.net/littlemonkeyc/blog/3001057

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Cfront 是一个用于将 C++ 程序翻译成 C 语言的编译器前端。下面是如何使用 Cfront 将 C++ 程序翻译成 C 语言的步骤: 1. 安装 Cfront:首先,需要下载并安装 Cfront 编译器。Cfront 是一个比较古老的工具,可以在一些历史文档中找到它的源码。一旦安装完成,确保将其添加到系统环境变量中,以便能在命令行中直接访问 Cfront。 2. 准备 C++ 源代码:将要翻译成 C 语言的 C++ 源代码保存到某个文件中,确保代码正确无误并且可以通过 Cfront 进行处理。 3. 执行 Cfront 命令:使用命令行工具进入保存源代码的目录,并执行以下命令:`cfront your_cpp_file.cpp` 4. 检查生成的 C 代码:Cfront 会将翻译后的 C 代码输出到一个名为 `your_cpp_file.C` 的文件中。打开该文件,检查生成的 C 代码是否正确。 5. 编译 C 代码:使用适当的 C 语言编译器来编译生成的 C 源代码。例如,如果您使用的是 GCC 编译器,可以执行以下命令:`gcc your_cpp_file.C -o your_output_file` 6. 运行 C 代码:编译成功后,运行生成的可执行文件,以验证翻译过程是否正确。 请注意,Cfront 是一个相对较旧的工具,并且可能不支持所有 C++ 特性。因此,在将 C++ 程序翻译为 C 的过程中,可能需要进行一些手动的修改和调整,以使代码正确且能够在 C 编译器中成功构建。 ### 回答2: Cfront是一个用于将C++代码转换为C代码的转译器。下面是使用Cfront将C++代码翻译成C代码的步骤: 1. 首先,确保你的系统上已经安装了Cfront。Cfront是一个早期的C++编译器,已经很少使用了,但你可能会在一些旧的系统上找到它。 2. 将C++源代码文件(例如example.cpp)放置在一个文件夹中,以便于使用Cfront进行处理。 3. 打开终端或命令提示符,并导航到包含C++源代码文件的文件夹。 4. 在命令行中使用Cfront命令,将C++代码翻译成C代码。命令应该类似于:cfront -c example.cpp 5. Cfront将处理C++代码,并将生成一个C代码文件。这个文件的文件名通常与C++源代码文件的文件名相同,只是文件扩展名不同(.c而不是.cpp)。 6. 最后,你可以使用任何C编译器(例如gcc或clang)对生成的C代码进行编译。例如,使用gcc命令编译生成的C代码文件:gcc -o example example.c 7. 现在你可以运行生成的可执行文件(例如example)来验证翻译的C代码是否按预期工作。 需要注意的是,由于Cfront是一个早期的C++编译器,它可能无法处理一些更现代的C++特性。此外,由于Cfront已经很少使用,它可能无法在所有系统上正常工作。在使用Cfront进行转译之前,请确保仔细阅读和理解相关文档,并对源代码进行适当的测试和验证。 ### 回答3: Cfront是一个将C++代码翻译成C代码的编译器前端。Cfront的输入是C++代码,其输出是等价的C代码。 使用Cfront将C++翻译成C的主要步骤如下: 1. 安装Cfront:首先需要从合适的来源(例如GitHub)上下载并安装Cfront编译器。 2. 编写C++代码:使用任何文本编辑器编写C++代码,并保存为.cpp文件。 3. 使用Cfront进行翻译:打开命令行终端,导航到保存C++代码的目录,并运行Cfront编译器,指定需要翻译的C++文件。 4. 检查翻译结果:Cfront会将翻译结果保存为等价的C代码。打开生成的C文件,检查并验证是否正确完成了翻译。 需要注意的是,Cfront在将C++代码翻译成C代码时会尽可能保留C++的语法结构和特性。但由于C和C++的语法差异,部分C++语法和特性无法完全翻译到C中,并且Cfront并不保证生成的C代码能够正确编译和运行。 此外,由于Cfront是一个早期的C++编译器前端,目前已经不再维护和更新。因此,在实际使用中,了解更现代和广泛使用的C++到C转换工具,如Emscripten和Cheerp等,可能更为实用和可靠。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值