Undefined symbol for class static variables with embind. Need help.

101 views
Skip to first unread message

キャロウ マーク

unread,
Dec 26, 2019, 1:32:19 PM12/26/19
to emscripten-discuss
I am trying to use embind to provide a JS API to some c/c++ code. The underlying code is c and I have a small wrapper to give it a proper c++ api. My file ktx_wrappers.cpp contains this c++ wrapper and the EMSCRIPTEN_BINDINGS. Due to the build system I am using, this is first compiled to a .o then in a second step linked with the underlying library, also previously compiled, to produce the .js file.

The wrapper class contains (simplified for illustration)

namespace ktx_wrappers
{
class texture
{
public:
...
static const uint32_t KTX_FOO = 1;
...
}
}

EMSCRIPTEN_BINDINGS contains

EMSCRIPTEN_BINDINGS(ktx_wrappers)
{
class_<ktx_wrappers::texture>("ktxTexture")
.class_property("KTX_FOO", &ktx_wrappers::texture::KTX_FOO)

;
}

This compiles fine but on link wasm-ld reports "undefined symbol: ktx_wrappers::texture::KTX_FOO”. llvm-nm on ktx_wrappers.o indeed shows that this symbol is undefined.

I am specifying —bind on both the compile & link commands.

How to I prevent the compiler removing this symbol? Is it being removed because none of the class texture methods reference this static class constant?

Regards

-Mark




signature.asc

Shachar Langbeheim

unread,
Dec 27, 2019, 12:38:38 AM12/27/19
to emscripten-discuss
Try either add '__attribute__((used))' or defining the constant as 'static inline'.

--
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/E89A8902-A981-43A2-8C04-6D9CAA99AF10%40callow.im.

Shachar Langbeheim

unread,
Dec 27, 2019, 12:40:59 AM12/27/19
to emscripten-discuss
The second solution assumes that you compile using c++17 or later.

キャロウ マーク

unread,
Dec 27, 2019, 12:48:42 AM12/27/19
to emscripten-discuss
I get the warning "'used' attribute ignored [-Wignored-attributes]”. I’m not using c++17 so can’t try the second.

Regards

    -Mark
signature.asc

キャロウ マーク

unread,
Dec 30, 2019, 8:35:27 PM12/30/19
to emscripten-discuss
The problem is that "static const uint32_t KTX_FOO = 1;” in the class declaration doesn’t actually define an object. I need to add

const uint32_t texture::KTX_FOO = 1;

after the class declaration. Then things work.

However this makes it very awkward to export values represented in an enum in the C++ API to Javascript. It has to be mentioned 3 times

class texture {
    static const uint32_t KTX_FOO;
};

const uint32_t KTX_FOO = static_cast<uint32_t>(c++_texture::enum_val);

and then in the bindings

.class_property(“KTX_FOO”, &wrapper::texture::KTX_FOO)

Is there anyway to automate this binding? IT is very tedious and error prone especially if ifdefs are involved.

Other than reading the source code, is there any complete documentation for embind? I haven’t been able to find any documents that mention class_property.

A happy New Year to all.

    -Mark


signature.asc

キャロウ マーク

unread,
Jan 6, 2020, 2:53:26 PM1/6/20
to emscripte...@googlegroups.com


On Dec 30, 2019, at 17:35, キャロウ マーク <git...@callow.im> wrote:

However this makes it very awkward to export values represented in an enum in the C++ API to Javascript. It has to be mentioned 3 times

class texture {
    static const uint32_t KTX_FOO;
};

const uint32_t KTX_FOO = static_cast<uint32_t>(c++_texture::enum_val);

and then in the bindings

.class_property(“KTX_FOO”, &wrapper::texture::KTX_FOO)

Is there anyway to automate this binding? IT is very tedious and error prone especially if ifdefs are involved.

I solved this with some pre-processor hackery. I don’t like it because the constant names are hidden in another file. Is there a better way?

Regards

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