Thanks for your help and patience. I'm making some good progress with the Nim-based approach. I can load code via node.js with -s MODULARIZE=1. Now, upon return from one of my functions, I get:

Invalid function pointer called with signature 'ii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? ( it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)
Build with ASSERTIONS=2 for more info.
5
5
failed to asynchronously prepare wasm: abort(5) at Error
    at jsStackTrace (/sysroot/home/nolan/Projects/waynav/waynav.js:1064:13)
    at stackTrace (/sysroot/home/nolan/Projects/waynav/waynav.js:1081:12)
    at abort (/sysroot/home/nolan/Projects/waynav/waynav.js:8167:44)
    at nullFunc_ii (/sysroot/home/nolan/Projects/waynav/waynav.js:6653:434)
    at b5 (wasm-function[9505]:3)
    at _mallocWithAlarm (wasm-function[5899]:62)
    at _sqlite3Malloc (wasm-function[5898]:145)
    at _sqlite3DbMallocRaw (wasm-function[5895]:90)
    at _sqlite3DbMallocZero (wasm-function[6239]:48)
    at _sqlite3FindFunction (wasm-function[7074]:580)
abort(5) at Error
... (2 more repetitions of the same stacktrace)


I'm not sure what that's telling me. I do have `-Werror -s ASSERTIONS=2` in my compiler options, but there are no warnings in either the compilation or link processes. My function is definitely being exported, as I've added print statements throughout, and the only line I can't bracket with prints is the return line. The code also works when I run it natively.


Does this mean I'm wrapping the function with the wrong return type? I'm trying to return a pointer, and have:


Module.newMap = Module.cwrap("newMap", "number", ["string"])


In Nim, the function is declared:


```

proc newMap*(path: cstring): ptr Map {.exportc.} =

```


`ptr Map` is a pointer to a Nim type, but `ptr` is supposed to emit C-style pointers, so I'd assume "number" is what I'd want on the JS side. If the issue is the return type, then I'll create a reproduction and post on the Nim forum for help with it. I just want to know what I might be dealing with before turning to the Nim folks for further help.


Thanks.




On 9/28/18 8:41 AM, Floh wrote:

IMHO C structs are also not the best solution for a simple cross-language interop layer, but a function-only API with primitive argument and return types (so additional accessor-functions are IMHO best, even if it means the API becomes a bit messy).

Look at the OpenGL API as an example: there are no structs anywhere, only functions with simple args, or at most pointers to 'unstructured data'. I only really noticed that this is a nice property after creating C APIs that use struct args. It's surprisingly hard to create bindings for this approach even for languages that have good C interop.

If you want to hand a pointer to "raw data" from C to JS, you can use cast the pointer to the 32-bit int (that's a bit smelly of course), hand this 'pointer-index' to JS as number, and use it as index into the global HEAP typed-array-views (and don't forget to divide the pointer-index by the view's datatype size.

For instance this snippet calls a C function from JS, the C function returns a pointer-index, which is used to access the Float32 heap-view:

            var ptr = Module.ccall('_saudio_emsc_pull', 'number', ['number'], [num_frames]);
            if (ptr) {
                var num_channels = event.outputBuffer.numberOfChannels;
                for (var chn = 0; chn < num_channels; chn++) {
                    var chan = event.outputBuffer.getChannelData(chn);
                    for (var i = 0; i < num_frames; i++) {
                        chan[i] = HEAPF32[(ptr>>2) + ((num_channels*i)+chn)]
                    }
                }
            }







On Thursday, 27 September 2018 22:43:55 UTC+2, Nolan Darilek wrote:

    Cool, thanks for the pointers. I think I'll be investigating
    abandoning
    Rust for Nim because of its better C interop, so it looks like I
    can use
    these functions/interfaces more directly.


    Assuming I'm building a nicer C-style interface between not-so-nice
    lower-level C and not-so-nice-for-its-own-reasons JS, I'm assuming
    the
    best strategy is modeling data with C-style structs, and modeling my
    wrapper functions to accept int32s representing pointers to those
    structs?


    If so, how should I go from pointers to JS objects? Or should I just
    treat the pointers as opaque from JS's perspective, write
    functions to
    access their data, then wrap those functions into JS getters? The JS
    side of this API is mostly read, with mutations happening by passing
    data to the C/Nim API, so opaqueness/getters would probably work
    if needed.


    Thanks for the help.


    On 9/23/18 1:33 PM, Alon Zakai wrote:
    > In emscripten, for simple C APIs you can just use the
    emscripten.h macro
    >
    > #define EMSCRIPTEN_KEEPALIVE __attribute__((used)) __attribute__
    > ((visibility ("default")))
    >
    > If rust lets you define those LLVM attributes somehow, then just
    > applying those to a function will export it so JS can call it.
    > However, that doesn't handle string conversions etc., which you can
    > use ccall/cwrap for. With cwrap you need to declare the
    functions you
    > are binding, but it automates all the conversions etc.
    >
    > For C++ you can also use embind and the WebIDL binder, which
    automate
    > even more conversions, emulating C++ objects as JS objects,
    etc., but
    > for C you probably don't need those.
    >
    > Overall it does seem like most Rust interest these days is in
    > wasm32-unknown-unknown, as they're writing new Rust for JS
    purposes,
    > as opposed to what you're doing. I think both use cases are
    important
    > though - actually as Rust becomes more common in native
    development, I
    > think porting Rust + C combinations will become more important.
    >
    >
    > On 9/22/18, Nolan Darilek <[email protected] <javascript:>>
    wrote:
    >> The Rust wasm community seems to prefer wasm32-unknown-unknown
    these
    >> days. Unfortunately, my use case needs C libraries that will
    never be
    >> rewritten. I have a fairly small API surface that I'm calling
    from Yew
    >> (Rust front-end framework) but I'm starting to think I'd be better
    >> served by trying to export that API surface to JS and switching
    the UI
    >> to a more traditional framework. Is this site still a good
    reference for
    >> how to do this?
    >>
    >>
    >> https://hoverbear.org/2017/04/06/the-path-to-rust-on-the-web/
    <https://hoverbear.org/2017/04/06/the-path-to-rust-on-the-web/>
    >>
    >>
    >> Specifically, it creates a C library wrapping the exported Rust
    >> functions, then an empty `main()`. Given how fast these
    ecosystems move,
    >> I was wondering if any of this work could be automated?
    wasm-bindgen is
    >> for wasm32-unknown-unknown if I understand correctly, but I
    thought I'd
    >> check that assumption.
    >>
    >>
    >> Are there any current examples of someone building JS modules
    using Rust
    >> and Emscripten? Or has everyone in the Rust community switched
    >> exclusively to wasm32-unknown-unknown?
    >>
    >>
    >> Thanks.
    >>
    >> --
    >> 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 [email protected]
    <javascript:>.
    >> For more options, visit https://groups.google.com/d/optout
    <https://groups.google.com/d/optout>.
    >>

--
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 [email protected] <mailto:[email protected]>.
For more options, visit https://groups.google.com/d/optout.

--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to