partridgejiang / cheminfo-to-web

An experimental project to recompile native chemoinformatics libs into JavaScript.
https://partridgejiang.github.io/cheminfo-to-web/
MIT License
13 stars 3 forks source link

Unable to get atom charge in Indigo JS bindings #6

Closed baoilleach closed 1 year ago

baoilleach commented 1 year ago

Hi @partridgejiang, thanks for all your work on this. I am using the Indigo bindings, and they are working really well and seem pretty fast.

I only have one problem, which you may know the answer to, or a solution for. Given an atom, I am unable to get the charge on it. This is because getCharge requires two parameters: the first is the handle to the atom, and the second is a pointer to an integer (to hold the return value). I've tried just passing in a JavaScript variable for the second parameter and that doesn't work. I was then thinking about using malloc to create a pointer and send it in. I think this might work, but I can't find the emscripten methods that would let me read that memory (getValue).

Have you come across this problem before? Any thoughts?

partridgejiang commented 1 year ago

Hi @baoilleach, the second *int parameter of C function can not be retrieved simply by a JavaScript number variable. Actually, in Emscripten, this type of C function is binded to JavaScript function with the following signature:

getCharge(number, array);

Then the returned value can be filled in array and be read out. The following code should work (although not tested by myself yet):

let a = [];
Indigo.getCharge(atomIndex, a);
let charge = a[0];

Please try it and let me know your result if possible, :).

partridgejiang commented 1 year ago

Hi @baoilleach, there used to be some incorrect parameter bindings in the exported JS functions. Just did some modification and please check the latest files in this repo. Now the getCharge can be called as the following:

let Indigo = CreateIndigo(module);   // module is the Indigo wasm module object
let IndigoModule = Indigo._module;
// ...
let buf = IndigoModule._malloc(4);  // malloc buf for int
Indigo.getCharge(atom, buf);
let charge = IndigoModule.getValue(buf, 'i32');
IndigoModule._free(buf);
baoilleach commented 1 year ago

If this works, that's awesome, but isn't it late at night there? Get some sleep :-) I'll tell you how it goes in the morning!

baoilleach commented 1 year ago

And it works! image