英文:
Having difficulty importing emscripten wasm c++ class into svelte component
问题
I understand your request to focus on translating the code portions. Here's the translated code:
#include <emscripten/emscripten.h>
#include <emscripten/val.h>
#include <emscripten/bind.h>
using namespace emscripten;
using emscripten::val;
using namespace std;
thread_local const val document = val::global("document");
class MyClass {
private:
val canvas;
val ctx;
public:
MyClass(std::string id) {
canvas = val::global("document").call<val>("getElementById", val(id));
ctx = canvas.call<val>("getContext", val("2d"));
}
void greenRect() {
emscripten_run_script("alert('greenrect')");
ctx.set("fillStyle", "green");
ctx.call<void>("fillRect", 10, 10, 150, 100);
}
~MyClass() {}
};
EMSCRIPTEN_BINDINGS(MyClassModule) {
class_<MyClass>("MyClass")
.constructor<std::string>()
.function("greenRect", &MyClass::greenRect);
}
And the script portion of the App.svelte component:
import { onMount } from "svelte";
import { MyClass } from "../em/glue.js";
onMount(async () => {
alert("pre");
const chart = new Module.MyClass("canvas0");
alert("post");
chart.greenRect();
});
I hope this helps you with your project. If you have any specific questions or need further assistance, please let me know.
英文:
I've been trying to use my c++ class in my svelte component, and been beating my head against the screen for the past week trying to figure out how to do this. I'm comfortable in c++ but not so much in JS, which I suspect is part of the issue.
My c++ code is :
#include <emscripten/emscripten.h>
#include <emscripten/val.h>
#include <emscripten/bind.h>
using namespace emscripten;
using emscripten::val;
using namespace std;
thread_local const val document = val::global("document");
class MyClass{
private :
val canvas;
val ctx;
public :
MyClass(std::string id){
canvas = val::global("document").call<val>("getElementById", val(id));
ctx = canvas.call<val>("getContext", val("2d") );}
void greenRect(){
emscripten_run_script("alert('greenrect')");
ctx.set("fillStyle", "green");
ctx.call<void>("fillRect", 10, 10, 150, 100);
}
~MyClass(){}};
EMSCRIPTEN_BINDINGS(MyClassModule) {
class_<MyClass>("MyClass")
.constructor< std::string>()
.function("greenRect", &MyClass::greenRect)
;}
In this example my life would probably be easier if I just switched to a C++ function rather than a class, but I would like to keep it as a class unless this is completely non-viable (which it shouldn't be).
My current invocation of the compiler is em++ -s ALLOW_MEMORY_GROWTH=1 -lembind -s USE_SDL=2 -s ENVIRONMENT='web' -s SINGLE_FILE=1 chart.cpp -o glue.js
The script portion of the App.svelte component is
import { onMount } from "svelte";
import { MyClass } from "../em/glue.js";
onMount(async () => {
alert("pre");
const chart = new Module.MyClass("canvas0");
alert("post");
chart.greenRect();
});
I get the "pre" popup but never the "post" popup.
I've tried several variations on the import
statement with import MyClass from 'glue.js'
, <script src ="glue.js">
in the svelte:header
section. I've also tried a variety of CLI options including-s MODULARIZE=1, -s EXPORT_ES6=1,-s EXPORT_ALL=1, -s WASM=1
none of which seem to fix this issue.
The problem is that I keep getting errors in the browser
import { MyClass } from 'glue.js'
-> "Uncaught SyntaxError: ambiguous indirect export: MyClass"
import * as MyClass from 'glue.js'
-> Uncaught (in promise) TypeError: Module.MyClass is not a constructor
import MyClass from 'glue.js'
-> Uncaught SyntaxError: ambiguous indirect export: default
I've also changed the const chart = new MyClass("canvas0")
to const chart = new Module.MyClass("canvas0");
and const chart = new MyClass.MyClass("canvas0");
Yup, JS is not my strong point and I'm admittedly just throwing stuff at the wall to see what sticks.
If someone could point me in the right direction I'd really appreciate it. I tried to get chatGPT and Bard to fix the issue and have come away feeling confident that coders' jobs are secure for the foreseeable future.
I appreciate any help you can give.
Thanks
答案1
得分: 1
I figured out the problem - for some reason I have to add echo 'export { Module };' >> glue.js
after which I change the Svelte code to
import { Module } from "../glue.js";
onMount(async () => {
Module.onRuntimeInitialized = async () => {
alert("pre");
const chart = new Module.MyClass("canvas0");
alert("post");
chart.greenRect();
};
});
Now everything runs as expected.
英文:
I figured out the problem - for some reason I have to add echo 'export { Module };' >> glue.js
after which i change the svelte code to
import { Module } from "../glue.js";
onMount(async () => {
Module.onRuntimeInitialized = async () => {
alert("pre");
const chart = new Module.MyClass("canvas0"); alert("post"); chart.greenRect(); }; });
Now everything runs as expected.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论