WebAssembly学习(三)——初步读取本地文件

WebAssembly学习(三)——初步读取本地文件

在之前的学习记录里面,已经实现了简单的hello word打印,在这一步学习如何利用SDL库打印图案以及加载文件,原文参考Emscripten的官网

利用SDL库打印图案

SDL库:SDL是一个跨平台的多媒体库,它通过OpenGL和2D视频帧缓冲,提供了针对音频、视频、键盘、鼠标、控制杆及3D硬件的低级别的访问接口。

测试例程代码如下:

// Copyright 2011 The Emscripten Authors.  All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License.  Both these licenses can be
// found in the LICENSE file.

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

#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

int main(int argc, char** argv) {
  printf("hello, world!\n");

  SDL_Init(SDL_INIT_VIDEO);
  SDL_Surface *screen = SDL_SetVideoMode(256, 256, 32, SDL_SWSURFACE);

#ifdef TEST_SDL_LOCK_OPTS
  EM_ASM("SDL.defaults.copyOnLock = false; SDL.defaults.discardOnLock = true; SDL.defaults.opaqueFrontBuffer = false;");
#endif

  if (SDL_MUSTLOCK(screen)) SDL_LockSurface(screen);
  for (int i = 0; i < 256; i++) {
    for (int j = 0; j < 256; j++) {
#ifdef TEST_SDL_LOCK_OPTS
      // Alpha behaves like in the browser, so write proper opaque pixels.
      int alpha = 255;
#else
      // To emulate native behavior with blitting to screen, alpha component is ignored. Test that it is so by outputting
      // data (and testing that it does get discarded)
      int alpha = (i+j) % 255;
#endif
      *((Uint32*)screen->pixels + i * 256 + j) = SDL_MapRGBA(screen->format, i, j, 255-i, alpha);
    }
  }
  if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
  SDL_Flip(screen); 

  printf("you should see a smoothly-colored square - no sharp lines but the square borders!\n");
  printf("and here is some text that should be HTML-friendly: amp: |&| double-quote: |\"| quote: |'| less-than, greater-than, html-like tags: |<cheez></cheez>|\nanother line.\n");

  SDL_Quit();

  return 0;
}

新建C++源文件,把上面代码粘贴进去。

使用emrun指令运行得到的HTML界面,得到的结果如下
在这里插入图片描述
在目前还不需要对媒体库应用有深入了解,本文先不对该部分的代码进行详细的解读,等待需要学习SDL库文件之后再进行分析。

加载文件

你的C/C++代码可以使用正常的libc stdio API(fopen、fclose等)访问文件。

JavaScript通常在网络浏览器的沙盒环境中运行,不能直接访问本地文件系统。Emscripten模拟了一个文件系统,你可以使用正常的libc stdio API从你编译的C/C++代码中访问它。

你想访问的文件应该被预装或嵌入到虚拟文件系统中。预装(或嵌入)生成一个虚拟文件系统,它与编译时的文件系统结构相对应,相对于当前目录。

下面的例子显示了如何加载一个文件(测试代码和要加载的文件都显示在下面):

// Copyright 2012 The Emscripten Authors.  All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License.  Both these licenses can be
// found in the LICENSE file.

#include <stdio.h>

int main() {
  FILE *file = fopen("test/wordTest.txt", "rb");
  if (!file) {
    printf("cannot open file\n");
    return 1;
  }
  while (!feof(file)) {
    char c = fgetc(file);
    if (c != EOF) {
      putchar(c);
    }
  }
  fclose (file);
  return 0;
}

这个例子希望能够加载一个位于test/wordTest.txt的文件。
我们编译这个例子从“test”目录上面的,以确保虚拟文件系统是以相对于编译时目录的正确结构创建的。
测试代码文件结构
在这里插入图片描述

以下命令用于指定一个数据文件,在运行任何编译的代码之前,预先加载到Emscripten的虚拟文件系统中。这种方法很有用,因为浏览器只能异步地从网络上加载数据(Web Workers除外),而很多本地代码都使用同步的文件系统访问。预加载可以确保在编译代码有机会访问Emscripten文件系统之前,数据文件的异步下载已经完成(而且文件是可用的)。

emcc .\fileTest.cpp -o fileTest.html --preload-file test/wordTest.txt

编译运行后,将HTML在web浏览器中运行就可以看到txt里面的内容被加载到浏览器中。
但是发现浏览器打印输出的数据里面有一部分消失:
在这里插入图片描述
保留对该问题的疑惑,进一步学习尝试解决这个问题。

更多的知识,可以查看文件系统概述文件系统API以及同步的虚拟XHR支持的文件系统使用教程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值