如何为C库编写自定义Emscripten填充程序?Emscripten捆绑了某些C库(如SDL和OpenAL)的填充程序,但是对于其他库,您将不得不自己动手.
通过shim我的意思是,一个C库的JavaScript替换要移植的代码取决于.
我有一个简单的C函数来修改整数数组的元素.我可以使用Emscripten(emcc)将其转换为JavaScript而不会出现问题.但是当我在JS数组上调用该函数时,其中的值似乎没有改变.请帮忙.
这是C函数定义:
/* modify_array.c */
void modify_array(int X[8]) {
int i;
for (i = 0; i < 8; ++i) {
X[i] += 1;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我用来将C代码转换为JS的命令:
emcc modify_array.c -o modify_array.js -s EXPORTED_FUNCTIONS="['_modify_array']"
Run Code Online (Sandbox Code Playgroud)
这是用于调用已转换的JS代码的JavaScript(Node.js)代码:
var mod = require("./modify_array.js");
var f = mod.cwrap("modify_array", "undefined", ["array"]);
var X = [0, 1, 2, 3, 4, 5, 6, 7];
var bytesX = new Uint8Array(new Int32Array(X).buffer);
/* Invoke the emscripten-transpiled function */
f(bytesX);
console.log(new Int32Array(bytesX.buffer));
Run Code Online (Sandbox Code Playgroud)
运行JS代码后,缓冲区包含的值与原始值相同,而不是递增的值.为什么?如何获取更新的值?
我正在运行 Windows 10,并且只是尝试安装 Emscripten。我已经安装了 Emscripten:
我跑
# Fetch the latest registry of available tools.
emsdk update
Run Code Online (Sandbox Code Playgroud)
其次是
# Download and install the latest SDK tools.
emsdk install latest
Run Code Online (Sandbox Code Playgroud)
但它继续发出关于无法找到 cmake 路径的相同警告。
我已经下载并安装了cmake-3.3.2-win32-x86。但是,我无法从安装中创建 PATH,因为它说文件长度太长。奇怪,因为它安装在这里:
C:\Program Files (x86)\CMake\bin
我想我可以自己设置路径,如this SO post所示。因此,我在上图之后使用了这个命令:
set PATH="C:\Program Files (x86)\CMake\bin\";%PATH%
Run Code Online (Sandbox Code Playgroud)
并有同样的问题。我的想法很新鲜。是否与安装了 64 位版本的 clang 和 sdk 的事实有关,但 Cmake 只有 32 位版本?
尝试使用用emscripten编译的c++代码连接到websocket(poco-1.9.0示例\WebSocketServer)。使用编译的 boost 1.69 和常见示例之一连接到套接字。
boost::asio::ssl::context ctxt(context::sslv23_client);
ctxt.set_verify_mode(boost::asio::ssl::verify_none);
boost::asio::io_service svc;
tcp::resolver resolver(svc);
tcp::resolver::query query("127.0.0.1", "9980",
boost::asio::ip::resolver_query_base::numeric_service);
tcp::resolver::iterator i = resolver.resolve(query, ec);
boost::asio::ssl::stream<tcp::socket> s(svc, ctxt);
s.lowest_layer().connect(*i, ec);
s.handshake(boost::asio::ssl::stream<tcp::socket>::client, ec);
Run Code Online (Sandbox Code Playgroud)
服务器输出如下
Request from 127.0.0.1:58152: GET / HTTP/1.1
Host: 127.0.0.1:9980
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://127.0.0.1:8887
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: binary
WebSocket connection established.
Frame received (length=0, flags=0x0).
WebSocket connection closed.
Run Code Online (Sandbox Code Playgroud)
但是,此代码在握手后挂起。可以这样使用还是需要使用 asio 的异步调用?
另外,如果您知道任何类似的例子,请分享。
我有一个 C++ 项目,我已使用 emscripten 将其转换为 javascript。我需要帮助通过节点实现文件输入到程序中。据我了解,emscripten 中的默认文件系统使用只能在网页或网络工作人员上完成的预加载数据。我需要我的在命令行上使用node.js。
查看文档,我发现有一种方法可以使用 NODEFS 而不是默认的 MEMFS,这应该允许我执行此操作。但是,我不确定该怎么做。我不太明白所提供的测试代码。
以下是原始 C++ 项目中文件处理的方式:
void InputFile(std::string &fileName)
{
std::ifstream in(fileName);
if (in.fail())
{
std::cerr << "ERROR, Could not open " << fileName << std::endl;
exit(1);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用文件运行转换后的程序时,node project.js -f test.file我收到错误消息:ERROR, Could not open test.file意味着打开文件失败。原始的 C++ 项目能够打开该文件,没有任何问题,所以我知道文件本身没有问题。
我不确定我必须做什么才能使转换后的项目与文件输入一起工作,任何帮助将非常感激。
我想创建一个 GitHub 工作流,使用 emscripten 和 cmake 构建 C++ 应用程序,并将其部署到 GitHub Pages。我的工作流程工作如下所示。
environment:
name: github-pages
url: ${{steps.deployment.outputs.page_url}}
runs-on: ubuntu-latest
container:
image: emscripten/emsdk
steps:
- uses: actions/checkout@v3
- run: cmake -B $GITHUB_WORKSPACE/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DEMSCRIPTEN=ON
- run: cmake --build $GITHUB_WORKSPACE/build --config ${{env.BUILD_TYPE}}
# actions/upload-pages-artifact uses this directory, but it doesn't exist in the image
- run: mkdir -p ${{runner.temp}}
- uses: actions/configure-pages@v1
- uses: actions/upload-pages-artifact@v1
with:
path: $GITHUB_WORKSPACE/build
- id: deployment
uses: actions/deploy-pages@v1
Run Code Online (Sandbox Code Playgroud)
upload-pages-artifact运行 tar 并在日志中列出要部署的所有文件。运行时upload-artifact日志显示Warning: No files were …
我正在尝试使用emscripten编译我的项目.在Visual Studio 2013中,一切都很好.
我在这里存储函数:
template<typename Return, typename ...Arguments>
using CBFunction = std::function<Return(Arguments...)>;
typedef unsigned int CBID;
template<typename Return, typename ...Arguments>
class CBCollection
{
std::map<CBID, CBFunction<Return, Arguments...>> cbs;
public:
CBID addCB(CBFunction<Return, Arguments...> cb)
{
CBID id = findFreeID();
cbs[id] = cb;
return id;
}
...
}
Run Code Online (Sandbox Code Playgroud)
后来我可以添加简单和成员函数:
CBCollection<void, MatrixStack, float> BeforeRenderCBs;
...
AnimatedSprite::AnimatedSprite()
{
using namespace placeholders;
BeforeRenderCBs.addCB(bind(&AnimatedSprite::beforeRenderCB, this, _1, _2));
}
Run Code Online (Sandbox Code Playgroud)
与emscripten这是结果:
<scratch space>:624:1: note: expanded from here
"C:/Development/LexUnitEngine/Engine/include/Buffer.h"
^
C:\Development\LexUnitEngine\Engine\source\AnimatedSprite.cpp:76:24: error: no viable conversion from '__bind<void (AnimatedSprite::*)(MatrixStack &, float), …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Emscripten将C库转换为可移植的JavaScript模块,该模块将由AMD(例如Require.JS)加载并提供对其功能和事物的访问:
require("vendor/mylib.js", function(mylib) {
mylib.function1();
});
Run Code Online (Sandbox Code Playgroud)
但是,我已经看到Emscripten使用大量变量污染全局命名空间,这违背了模块应该独立且不与其他已加载模块冲突的前提.
所以问题是:在AMD使用Emscrpiten的最佳方法是什么?
有没有办法告诉Emscripten不泄漏任何东西global?
如何验证函数是否在C++程序中内联展开?我的编译器是Emscripten,但答案g++可能有效.
理想情况下,在内联模式下运行的代码不同(尽管它不应该有任何副作用).
我想使用Emscripten编译一个C++代码,我在其中使用了一些C++ 11特性.不幸的是我收到一个错误:
index.cpp:13:18: error: expected expression
vv.push_back({1.5f, 2.f});
^
index.cpp:14:18: error: expected expression
vv.push_back({5.f, 0});
^
index.cpp:15:18: error: expected expression
vv.push_back({1, 1});
^
index.cpp:17:9: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for(auto& item : vv) {
^
index.cpp:17:20: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for(auto& item : vv) {
Run Code Online (Sandbox Code Playgroud)
我无法理解,为什么我会得到这个错误.最新的Emscripten和Clang版本使用激活emsdk.
代码是:
#include<iostream>
#include<vector>
struct AA {
float a;
float b;
};
int main() {
std::vector<AA> vv;
vv.push_back({1.5f, 2.f});
vv.push_back({5.f, 0});
vv.push_back({1, 1});
for(auto& …Run Code Online (Sandbox Code Playgroud) emscripten ×10
c++ ×5
c ×2
c++11 ×2
javascript ×2
llvm ×2
node.js ×2
webassembly ×2
arrays ×1
asm.js ×1
boost ×1
c++14 ×1
clang ×1
github-pages ×1
module ×1
shim ×1
stl ×1