我已将程序编译为单个program.js文件,并在工作程序中调用:
importScripts('program.js');
Module.callMain();
Run Code Online (Sandbox Code Playgroud)
然而,尽管callMain正在执行,但在该函数调用的堆栈中我收到了错误Undefined is not a function。
我的预感是我还没有阅读一些必要的emscripten文档、wiki 或源代码。
emcc传递特殊选项(请参阅settings.js)window/dev/tty在查看了与 by 链接的 的实现/dev/stdin以及 的实现之后/dev/stdout,我相信可能会有输出到console,我不认为工作人员支持该输出program.data(如果这有影响的话)提前致谢。如果我可以添加任何详细信息,请告诉我。
注意:顶部的代码经过简化 - 它似乎不是语法错误。
Error.stack) 仅告诉我错误发生在Module.callMain. 它没有告诉我任何有关可能导致该问题的导入脚本的信息。:(所以我有一个相当简单的 C++ 程序,它使用CGAL并使用 CMake 构建。我可以在没有 emscripten 的情况下成功构建并运行它:
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -G "Unix Makefiles" .
[output looks good]
make
[command works]
Run Code Online (Sandbox Code Playgroud)
一切都很好,我可以运行输出,但是当我尝试像这样使用 Emscripten 时(这在过去对我有用):
cmake -DCMAKE_TOOLCHAIN_FILE=/home/brenden/emsdk_portable/emscripten/master/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -G "Unix Makefiles" .
[output looks good]
make
main.cpp:2:10: fatal error: 'CGAL/Triangulation_3.h' file not found
#include <CGAL/Triangulation_3.h>
^
1 error generated.
ERROR root: compiler frontend failed to generate LLVM bitcode, halting
make[2]: *** [CMakeFiles/cgal_test.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/cgal_test.dir/all] Error 2
make: *** [all] Error 2
Run Code Online (Sandbox Code Playgroud)
这显然是行不通的。
我的 CMakeLists.txt 如下所示:
cmake_minimum_required(VERSION …Run Code Online (Sandbox Code Playgroud) 我有画布的图像数据:
myImage = ctx.getImageData(0, 0, 640, 480);
Run Code Online (Sandbox Code Playgroud)
我发现,我可以创建新的Uint8Array并用于set()复制图像数据。这是工作示例:
var numBytes = width * height * 4;
var ptr= Module._malloc(numBytes);
var heapBytes= new Uint8Array(Module.HEAPU8.buffer, ptr, numBytes);
heapBytes.set(new Uint8Array(myImage.data));
_processImage(heapBytes.byteOffset, width, height);
myImage.data.set(heapBytes);
Run Code Online (Sandbox Code Playgroud)
但是,不幸的是,每个.set()操作都比处理图像慢得多,并且上面的代码比 JS 实现慢!
所以,我想处理图像而不复制它。我可以通过这种方式成功地将数据直接读取和写入到堆中:
Module.HEAPU8.set(myImage.data, myImage.data.byteOffset);
_processImage(myImage.data.byteOffset, width, height);
myImage.data.set(new Uint8ClampedArray(Module.HEAPU8.buffer , myImage.data.byteOffset , numBytes));
Run Code Online (Sandbox Code Playgroud)
它更快,但第一个.set()执行仍然需要 17 毫秒。
C++函数原型为:
extern "C" {
int processImage(unsigned char *buffer, int width, int height)
{
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法将数组传递给C++而不使用set()?只是告诉c++数据在内存中的位置,并允许修改它?
我想创建一个函数来计算一些东西。完成后,它会调用回调函数。
void calculate(int param1, ..., std::function<void(void)> callback) {
//code...
callback();
}
Run Code Online (Sandbox Code Playgroud)
函数的绑定是使用以下命令创建的Embind:
EMSCRIPTEN_BINDINGS(my_module) {
function("calculate", &calculate);
}
Run Code Online (Sandbox Code Playgroud)
但如果我尝试打电话,Module.calculate(0, ..., function(){/*...*/})我会收到此错误:
UnboundTypeError: Cannot call calculate due to unbound types: NSt3__18functionIFvvEEE
Run Code Online (Sandbox Code Playgroud) 当使用 emscripten 不带任何参数编译 C++ 时,除了 webgl 画布之外,它还会生成一个带有控制台和 emscripten 徽标的 html 文件。
是否可以禁用 logo\console 并让它为填充 webgl 画布的空白网页生成 html\js ?
重新表述一下问题:
当我先验不知道数组的长度时,我应该如何将一个从 C/C++ API 返回一个以数组作为成员变量的对象的函数绑定到 javascript?
我有一个带有原始数据类型指针的结构
struct Person
{
const char* name;
int age;
Person()
{}
};
Run Code Online (Sandbox Code Playgroud)
我有一个函数应该返回这个结构的对象
Person getPerson()
{
Person p = Person();
p.name = "Philipp";
p.age = 77;
return p;
}
Run Code Online (Sandbox Code Playgroud)
以及以下约束:
EMSCRIPTEN_BINDINGS() {
value_object<Person>("Person")
.field("age", &Person::age)
.field("name", &Person::name)
;
function("getPerson", &getPerson);
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,编译器还告诉我,static_assert failed "Implicitly binding raw pointers is illegal. Specify allow_raw_pointer<arg<?>>"
我试图理解API 文档,但无法使其工作。例如,我尝试将allow_raw_pointer()(及其变体)添加到 of.field中name。
我想了解 Rust 程序在编译为 wasm 文件时实际导出的内容,以便我可以importObject为实例化函数提供有效的值:
WebAssembly.instantiate(bufferSource, importObject);
Run Code Online (Sandbox Code Playgroud)
据我了解,执行此操作的唯一方法是导出已编译代码的类似 s 语法的文件。我无法在他们的文档中或通过网络搜索找到如何执行此操作。
我正在尝试使用 ghcjs 将 haskell 库minisat移植到 JavaScript,以便集成到更大的 haskell-ghcjs 项目中。
minisat 包含几个来自 ac 库的 ffi 导入。我已经设法使用 emscripten 将 c 库编译为 javascript,并导出 minisat 所需的函数。到目前为止,一切都很好。
然而,有一些导入看起来像这样:
foreign import ccall safe minisat_solve :: Solver -> Int -> Ptr (Lit) -> IO (Bool)
它导入一个如下所示的函数:
int minisat_solve(minisat_solver *s, int len, minisat_Lit *ps)
根据文档,我的理解是,当 emscripten 导出一个接受或返回指针的函数时,该指针将变成 JavaScript 数字类型。
ghcjs 文档表明,应该可以通过适当包装 JavaScript 函数来保留现有的外部导入。然而,ghcjs 将指针类型表示为大致由 JavaScript 对象和数字组成的一对。
我认为包装代码应该大致是
function h$minisat_solve(...){
...
minisat_solve(...)
...
}
function minisat_solve = Module.cwrap('minisat_solve',...,...)
Run Code Online (Sandbox Code Playgroud)
但我对类型不匹配感到困惑。
ccall因此,挑战如下:使用ghcjs上面的包装器代码作为示例(或者反例,如果我完全错误的话)解释如何正确包装 emscripten 导出以供导入
我正在尝试按照教程在网络工作人员中运行 emscripten 构建的网络程序集。
当我实例化我的模块时,我得到了WebAssembly Instantiation: Import #9 module="global" error: module is not an object or function.
这是我的代码,用于生成一个工作程序并向其发送已编译的模块:
var g_worker = new Worker('worker.js');
WebAssembly.compileStreaming(fetch('my_module.wasm'))
.then(module => {
g_worker.postMessage(module);
});
Run Code Online (Sandbox Code Playgroud)
工人.js:
self.onmessage = function (evt) {
var module = evt.data;
var config = {
env: {
memoryBase: 0,
tableBase: 0,
memory: new WebAssembly.Memory({initial: 256}),
table: new WebAssembly.Table({initial: 0, element: 'anyfunc'})
},
imports: {
imported_func: function(arg) {
console.log(arg);
}
}
};
WebAssembly.instantiate(module, config);
}
Run Code Online (Sandbox Code Playgroud)
我用这些标志构建我的模块:
-I include \
-I …Run Code Online (Sandbox Code Playgroud) 我一直在尝试将第三方库链接到我的程序。工具链使用 Clang 4.0.0 进行编译(emscripten 1.37.19 在工具链中使用 clang)。我收到有关 __declspec 的错误,查找后发现我需要将 -fdeclspec 参数添加到 clang 中。但是,现在我收到此警告:
warning: __declspec attribute 'dllimport' is not supported [-Wignored-attributes]
Run Code Online (Sandbox Code Playgroud)
Clang 4.0 文档说应该支持这个属性。我在这里错过了什么吗?
emscripten ×10
c++ ×6
javascript ×5
web-worker ×2
webassembly ×2
asm.js ×1
c ×1
canvas ×1
cgal ×1
clang ×1
cmake ×1
compilation ×1
frontend ×1
ghcjs ×1
haskell ×1
lambda ×1
pointers ×1
rust ×1