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.