embind questions

31 views
Skip to first unread message

キャロウ マーク

unread,
May 17, 2024, 10:46:42 PMMay 17
to emscripten-discuss Sam Clegg via
I have 2 issues. Despite much time poring over embind.html and bind.h I’ve been unable to find a solution.

I have a struct in c that contains a uint32_t field that is set from values in an enum.

typedef struct {
   uint32_t format;
    …
} foo;

enum Format { A = 5, B = 6};

In my EMSCRIPTEN_BINDINGS block I have

  enum_<Format>("Format")
      .value(“A", A)
      .value(“B", B)
  ;

  emscripten::class_<foo>(“foo")
    .constructor<>()
    .property(“format", &foo::format)
    ...
  ;

In JS I have

var foo = new foo();


foo.format = Format.A;


format is always set to zero. To get it set to the correct value I have to write

foo.format = Format.A.value;

I don’t want users of my API to need to know they have to do this. Is there a way to avoid it, by modifying the declaration of the .property, by using something other than an enum_<> to declare the possible values or some other way? I don’t want to modify the underlying c API.



The second issue is that in a separate Params struct I have a field that is 

char swizzle[4];

With

.property(“swizzle", &Params::swizzle)

in the class binding, I get 

/emsdk/upstream/emscripten/cache/sysroot/include/emscripten/wire.h:349:16: error: array 'new' cannot have initialization arguments
  349 |         return new T(v);

How do I properly declare this property?

Regards

    -Mark

signature.asc

Brendan Dahl

unread,
May 21, 2024, 2:34:20 PMMay 21
to emscripten-discuss
For the first question, you could use a getter/setter e.g.
    .property("format", +[](const foo& a) {
      return a.format;
    },
    +[](foo& a, Format value) {
      a.format = value;
    })

For the second, char arrays are not currently bindable. Depending on what you're trying to do you can use either: std:string, a vector of chars (register_vector), or a memory_view. 

キャロウ マーク

unread,
May 25, 2024, 6:40:50 AMMay 25
to emscripten-discuss Sam Clegg via
Brendan,

Thank you very much for your reply. I have got these all working now. Without your help I am sure it would have taken me a long time to figure out the syntax.

I have another question that arose during the work. On the JS side the returned enum, Format in this case, appears as an object.

signature.asc
Screenshot 2024-05-25 at 19.37.37.png

キャロウ マーク

unread,
May 27, 2024, 3:40:58 AMMay 27
to emscripten-discuss Sam Clegg via
Another question just arose. I don’t see an answer in the embind documentation.

Is it possible to make aliases of items in the interface being bound with embind? Obviously I could just repeat a definition with the alternate name but that is error prone and I worry it would unnecessarily bloat the code.

I want to rename some items in my interface with breaking existing users.

Regards

    -Mark

<Screenshot 2024-05-25 at 19.37.37.png>

How can I compare two of these for equality?


signature.asc

キャロウ マーク

unread,
Jun 1, 2024, 4:40:56 AMJun 1
to emscripten-discuss Sam Clegg via
I have to ask this question again.

On May 27, 2024, at 16:40, キャロウ マーク <git...@callow.im> wrote:

Is it possible to make aliases of items in the interface being bound with embind? Obviously I could just repeat a definition with the alternate name but that is error prone and I worry it would unnecessarily bloat the code.

I want to rename some items in my interface with breaking existing users.

I’ve tried creating a .js file with the following and using it with --pre-js and —post-js


    Module['ktxTexture'] = texture;

and

    Module['ktxTexture'] = Module.texture;

and

    !function() {
        Module['ktxTexture'] = Module.texture;
    }();

“ktxTexture" is the old name, “texture” is the current name of the class.

In all cases ktxTexture is added to the module but it is always undefined. texture & Module.texture do not appear to (yet) be defined when the above code is executed, even with the IIFE.

Whatever adds the aliases needs to do so without relying on the name of the module instance as that it something user specific.

Regards

    -Mark


signature.asc

キャロウ マーク

unread,
Jun 1, 2024, 10:07:14 PMJun 1
to emscripten-discuss Sam Clegg via


On Jun 1, 2024, at 17:40, キャロウ マーク <git...@callow.im> wrote:


I’ve tried creating a .js file with the following and using it with --pre-js and —post-js


    Module['ktxTexture'] = texture;

and

    Module['ktxTexture'] = Module.texture;

and

    !function() {
        Module['ktxTexture'] = Module.texture;
    }();

“ktxTexture" is the old name, “texture” is the current name of the class.

In all cases ktxTexture is added to the module but it is always undefined. texture & Module.texture do not appear to (yet) be defined when the above code is executed, even with the IIFE.

Whatever adds the aliases needs to do so without relying on the name of the module instance as that it something user specific.


I created a —post-js containing

console.log(Module.texture)
Module['ktxTexture'] = Module.texture;

When run normally the console output tells me Module.texture is “undefined”. However after I had been stepping through the startup code the above worked. This made me realize that post-js is being run before Module is fully initialized. For some reason I thought it was run when everything was ready. I changed to

Module.onRuntimeInitialized = function() {
  Module['ktxTexture'] = Module.texture;
}

and it now works.

This could obviously be put in —pre-js instead. Which is better? Is there a chance that runtime initialization might have completed before —post-js code is run so the function will never be called?

Regards

    -Mark



signature.asc

Sam Clegg

unread,
Jun 2, 2024, 9:12:14 PMJun 2
to emscripte...@googlegroups.com
Better to set your `onRuntimeInitialized` in pre-js since that works even for projects that use `-sWASM_ASYNC_COMPILATION=0`

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/71483935-8D80-4C5C-AB3B-E0788578AC49%40callow.im.

キャロウ マーク

unread,
Jun 5, 2024, 11:07:56 PMJun 5
to emscripten-discuss Sam Clegg via


On Jun 3, 2024, at 10:11, 'Sam Clegg' via emscripten-discuss <emscripte...@googlegroups.com> wrote:

Better to set your `onRuntimeInitialized` in pre-js since that works even for projects that use `-sWASM_ASYNC_COMPILATION=0`

Thank you Sam. I have followed your advice.

Regards

    -Mark

signature.asc
Reply all
Reply to author
Forward
0 new messages