无法使NaCl C ++模块从打包的应用程序内加载文件 [英] Can't get NaCl C++ module to load file from within packaged app

查看:107
本文介绍了无法使NaCl C ++模块从打包的应用程序内加载文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个chrome打包的应用程序,该应用程序还包括PNaCl/NaCl C ++模块以及NaCl模块需要读取的一些数据文件.但是,我无法从文件中读取它.

I have a chrome packaged app that also includes a PNaCl/NaCl C++ module, as well as some data files which the NaCl module needs to read in. However, I am not able to get it to read in the files.

我根据我能找到的所有文档和官方示例以及对以下内容的回答进行了设置:

I set it up according to all the documentation and official examples that I could find, as well as the answer to: How to include a data file in a chrome app for a native client module to read

SDK附带的nacl_io演示程序可以做到这一点,但是它是用C语言编写的,而不是C ++语言.

The nacl_io demo that comes with the SDK is able to do this, but it is in C, not C++.

我想出了一个简单的示例,将在下面发布.当您按页面上的按钮时,NaCl模块应加载test.txt的第一个字符并显示它.到目前为止,它始终只以"-100"(我输入的错误值)作为响应,这意味着它无法打开文件,而不是文件的第一个字符.

I came up with a simple example, which I'll post below. When you press the button on the page, the NaCl module should load the first character of test.txt and show it. As of now, it always just responds with "-100" (the error value I put in), meaning that it could not open the file, rather than with the first character of the file.

任何人都可以提出一些建议,使其能够正常工作并加载文件吗?

Can anyone suggest some changes that would allow it to work correctly and load the file?

为了至少在Mac上运行它,我将以下命令与./file-test目录中的所有文件一起使用: /Applications/Google \ Chrome.app/Contents/MacOS/Google \ Chrome --load-and-launch-app =./file-test

In order to run it, on the Mac at least, I use this command, with all the files in the ./file-test dir: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --load-and-launch-app=./file-test

请注意,如果您尝试使用此功能,则很可能需要更改makefile中的NACL_SDK_ROOT路径.

Note that if you try to use this, you will most likely need to change the NACL_SDK_ROOT path in the makefile.

#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"

#include "nacl_io/nacl_io.h"
#include "sys/mount.h"

class FileTestInstance : public pp::Instance {
 public:
  explicit FileTestInstance(PP_Instance instance) : pp::Instance(instance)
  {
    // initialize nacl file system
    nacl_io_init_ppapi(instance, pp::Module::Get()->get_browser_interface());

    // mount the http root at /http
    mount("", "/http", "httpfs", 0, "");
  }
  virtual ~FileTestInstance() {}

  // Receive message from javascript
  virtual void HandleMessage(const pp::Var& var_message) {
    // Open and load from the file  
    int c;
    FILE *file;
    file = fopen("/http/test.txt", "r");
    if (file) {
        c = getc(file);
        fclose(file);
    } else {
        c = -100;
    }

    // Send message to JavaScript
    pp::Var var_reply(c);
    PostMessage(var_reply);
  }
};

class FileTestModule : public pp::Module {
 public:
  FileTestModule() : pp::Module() {}
  virtual ~FileTestModule() {}

  virtual pp::Instance* CreateInstance(PP_Instance instance) {
    return new FileTestInstance(instance);
  }
};

namespace pp {
Module* CreateModule() {
  return new FileTestModule();
}
}  // namespace pp

index.html

<!DOCTYPE html>
<html>
<head>
  <title>File Test</title>
 <script type="text/javascript" src="script.js"></script>
</head>
<body>

  <h1>File Test</h1>

  <input type="button" id="test" name="test" value="Test" />

  <p><b>Output:</b><p>
  <div id="output">
  </div>

  <p>
    <div id="listener">
      <embed id="file_test" width=0 height=0 src="file_test.nmf" type="application/x-pnacl" />
    </div>
  </p>
</body>
</html>

script.js

// outgoing messages
function postMessage(message) {
 var nacl_module = document.getElementById('file_test')
 nacl_module.postMessage(message);
}

// incoming messages
function handleMessage(message_event) {
  var outputDiv = document.getElementById('output');
  outputDiv.textContent = message_event.data;
}

// button action
function buttonClicked() {
    postMessage("file");
}

// set up
function init() {
    // add listener to nacl module
    var listener = document.getElementById('listener');
    listener.addEventListener('message', handleMessage, true);

    // add action to button
    document.getElementById("test").onclick = buttonClicked;
}

window.onload = init;

main.js

/**
 * Listens for the app launching then creates the window
 */
chrome.app.runtime.onLaunched.addListener(function() {
  // Center window on screen.
  var screenWidth = screen.availWidth;
  var screenHeight = screen.availHeight;
  var width = 600;
  var height = 600;

  chrome.app.window.create('index.html', {
    id: "File-TestID",
    bounds: {
      width: width,
      height: height,
      left: Math.round((screenWidth-width)/2),
      top: Math.round((screenHeight-height)/2)
    }
  });
});

file_test.nmf

{
  "program": {
    "portable": {
      "pnacl-translate": {
        "url": "file_test.pexe"
      }
    }
  }
}

Makefile

#
# Get pepper directory for toolchain and includes.
#
# If NACL_SDK_ROOT is not set, then assume where it can be found.
#
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
NACL_SDK_ROOT ?= $(abspath $(dir $(THIS_MAKEFILE))../../nacl_sdk/pepper_33)

# Project Build flags
WARNINGS := -Wno-long-long -Wall -Wswitch-enum -pedantic -Werror
CXXFLAGS := -pthread -std=gnu++98 $(WARNINGS)

#
# Compute tool paths
#
GETOS := python $(NACL_SDK_ROOT)/tools/getos.py
OSHELPERS = python $(NACL_SDK_ROOT)/tools/oshelpers.py
OSNAME := $(shell $(GETOS))
RM := $(OSHELPERS) rm

PNACL_TC_PATH := $(abspath $(NACL_SDK_ROOT)/toolchain/$(OSNAME)_pnacl)
PNACL_CXX := $(PNACL_TC_PATH)/bin/pnacl-clang++
PNACL_FINALIZE := $(PNACL_TC_PATH)/bin/pnacl-finalize
CXXFLAGS := -I$(NACL_SDK_ROOT)/include -I$(NACL_SDK_ROOT)/include/pnacl
LDFLAGS := -L$(NACL_SDK_ROOT)/lib/pnacl/Release -lppapi_cpp -lppapi -lnacl_io

#
# Disable DOS PATH warning when using Cygwin based tools Windows
#
CYGWIN ?= nodosfilewarning
export CYGWIN


# Declare the ALL target first, to make the 'all' target the default build
all: file_test.pexe

clean:
    $(RM) file_test.pexe file_test.bc

file_test.bc: file_test.cc
    $(PNACL_CXX) -o $@ $< -O2 $(CXXFLAGS) $(LDFLAGS)

file_test.pexe: file_test.bc
    $(PNACL_FINALIZE) -o $@ $<

test.txt

AAAA

推荐答案

在native-client-discuss列表中的Sam Clegg中:

From Sam Clegg on the native-client-discuss list:

我认为您遇到的主要问题是,您正在尝试在主线程上使用nacl_io.nacl_io,就像它主要基于的阻塞PPAPI接口一样,将仅在允许阻塞调用的后台线程上起作用.看: https://developer.chrome.com/native-client/devguide/coding/nacl_io ."

"I think the main problem you have is that you are trying to use nacl_io on the main thread. nacl_io, like the blocking PPAPI interfaces on which it is mostly based, will only work on background threads where blocking calls are allowed. See: https://developer.chrome.com/native-client/devguide/coding/nacl_io."

尝试在单独的线程上运行代码.一种简单的方法是使用ppapi_simple库."

"Try running your code on a separate thread. One easy way to do this is to use the ppapi_simple library."

使用此建议,并查看SDK随附的using_ppapi_simple,flock和earth的示例,我能够制作一个有效的版本:

Using this advice, and also looking at the examples using_ppapi_simple, flock, and earth, that are included with the SDK, I was able to make a working version:

#include <stdio.h>
#include "sys/mount.h"

#include <ppapi/cpp/var.h>
#include "ppapi_simple/ps_main.h"
#include "ppapi_simple/ps_event.h"
#include "ppapi_simple/ps_interface.h"


int file_test_main(int argc, char* argv[]) {
    PSEventSetFilter(PSE_ALL);

    // mount the http root at /http
    mount("", "/http", "httpfs", 0, "");

    while (true) {
        PSEvent* ps_event;
        // Consume all available events
        while ((ps_event = PSEventWaitAcquire()) != NULL) {
            // handle messages from javascript
            if (ps_event->type == PSE_INSTANCE_HANDLEMESSAGE) {
                // Convert Pepper Simple message to PPAPI C++ vars
                pp::Var var_message(ps_event->as_var);
                // process the message if it is a string
                if (var_message.is_string()) {
                    // get the string message
                    std::string message = var_message.AsString();

                    // handle message
                    if (message == "file") {
                        // Open and load from the file  
                        int c;
                        FILE *file;
                        file = fopen("/http/test.txt", "r");
                        if (file) {
                            c = getc(file);
                            fclose(file);
                        } else {
                            c = -100;
                        }

                        // Send response back to JavaScript
                        pp::Var var_reply(c);
                        PSInterfaceMessaging()->PostMessage(PSGetInstanceId(), var_reply.pp_var());
                    }
                }
            }

            PSEventRelease(ps_event);
        }
    }

    return 0;
}

/*
 * Register the function to call once the Instance Object is initialized.
 * see: pappi_simple/ps_main.h
 */
PPAPI_SIMPLE_REGISTER_MAIN(file_test_main)

此外,有必要将-lppapi_simple添加到Makefile中的LDFLAGS.

In addition, it is necessary to add -lppapi_simple to LDFLAGS in Makefile.

还可以自行处理线程,而不用使用ppapi_simple,这可以在SDK附带的nacl_io_demo中看到.

It would also be possible to do this handling the threads oneself, rather than using ppapi_simple, which can be seen in nacl_io_demo which is included with the SDK.

这篇关于无法使NaCl C ++模块从打包的应用程序内加载文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆