遇到了难以将Emscripten的Wasm C++类导入到Svelte组件中的问题。

huangapple go评论71阅读模式
英文:

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 &lt;emscripten/emscripten.h&gt;
#include &lt;emscripten/val.h&gt;
#include &lt;emscripten/bind.h&gt;

using namespace emscripten;
using emscripten::val;
using namespace std;
thread_local const val document = val::global(&quot;document&quot;);

class MyClass{
  private :
  val canvas;
  val ctx;
  public :
MyClass(std::string id){
  canvas = val::global(&quot;document&quot;).call&lt;val&gt;(&quot;getElementById&quot;, val(id));
  ctx = canvas.call&lt;val&gt;(&quot;getContext&quot;, val(&quot;2d&quot;) );}

void greenRect(){
   emscripten_run_script(&quot;alert(&#39;greenrect&#39;)&quot;);
   ctx.set(&quot;fillStyle&quot;, &quot;green&quot;);
   ctx.call&lt;void&gt;(&quot;fillRect&quot;, 10, 10, 150, 100);
 }
 ~MyClass(){}};

  EMSCRIPTEN_BINDINGS(MyClassModule) {
   class_&lt;MyClass&gt;(&quot;MyClass&quot;)
     .constructor&lt; std::string&gt;()
     .function(&quot;greenRect&quot;, &amp;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=&#39;web&#39; -s SINGLE_FILE=1 chart.cpp -o glue.js

The script portion of the App.svelte component is

  import { onMount } from &quot;svelte&quot;;
  import { MyClass } from &quot;../em/glue.js&quot;;
  onMount(async () =&gt; {
    alert(&quot;pre&quot;);
    const chart = new Module.MyClass(&quot;canvas0&quot;);
    alert(&quot;post&quot;);
    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 &#39;glue.js&#39;, &lt;script src =&quot;glue.js&quot;&gt; 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 &#39;glue.js&#39; -> "Uncaught SyntaxError: ambiguous indirect export: MyClass"
import * as MyClass from &#39;glue.js&#39; -> Uncaught (in promise) TypeError: Module.MyClass is not a constructor
import MyClass from &#39;glue.js&#39; -> Uncaught SyntaxError: ambiguous indirect export: default
I've also changed the const chart = new MyClass(&quot;canvas0&quot;) to const chart = new Module.MyClass(&quot;canvas0&quot;); and const chart = new MyClass.MyClass(&quot;canvas0&quot;);

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 &#39;export { Module };&#39; &gt;&gt; glue.js after which i change the svelte code to

import { Module } from &quot;../glue.js&quot;;
onMount(async () =&gt; {
    Module.onRuntimeInitialized = async () =&gt; {         
alert(&quot;pre&quot;);
      const chart = new Module.MyClass(&quot;canvas0&quot;);                                                       alert(&quot;post&quot;);                                    chart.greenRect();                              };                                              });

Now everything runs as expected.

huangapple
  • 本文由 发表于 2023年5月11日 12:32:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76224181.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定