I'm doing exactly that in my YAKC 
emulator: http://floooh.github.io/virtualkc/ (click on hamburger-menu icon 
-> load file... -> "Load" button).

The file picker HTML element is 
here: 
https://github.com/floooh/yakc/blob/master/web/_includes/load-panel.html#L1

The 'load_files()' JS function is called when the user has selected a file 
(also when drag'n'dropped a file into the load 
panel): https://github.com/floooh/yakc/blob/master/web/emsc.js#L141

And here's the C function that takes the file content as a pointer/length 
pair: https://github.com/floooh/yakc/blob/master/src/yakcapp/Main.cc#L463

Btw, a much nicer alternative to emscripten_runscript() for embedding JS 
code into the C source is via EM_JS():

See here for 
instance: 
https://github.com/floooh/chips-test/blob/bbe01867b9a3e06094c2805174294de99812addb/examples/common/args.h#L94-L105

You can call this 'inline' JS function like a normal C 
function: 
https://github.com/floooh/chips-test/blob/bbe01867b9a3e06094c2805174294de99812addb/examples/common/args.h#L114

Hope this helps!
-Floh

On Thursday, 6 September 2018 20:07:25 UTC+2, Treyten Carey wrote:
>
> Hi,
>
> This isn't necessarily an Emscripten issue but I thought this was a good 
> place for this question since I need to call C from JavaScript through 
> Emscripten.
>
> *What I'm trying to do:*
> The user should be able to select a WebGL button. The button calls an HTML 
> input file which brings up File Explorer to select a file (such as a txt 
> file or image). When the user selects a file (including a binary file), the 
> contents get sent from JavaScript to C, where C then writes the file to the 
> Emscripten local file system directory and where I should be able to send 
> the contents of the file over C sockets (this is why I need to be able to 
> get binary file contents, because I will be doing things with it in C).
>
> *What I've tried:*
> My HTML has an input element:
> <input id="file-input" type="file" name="name" style="display: none;"/>
>
> In my C code, when the user presses the WebGL button, I select the 
> file-input element to open the file selection:
> emscripten_run_script(
>         (char*)((std::string)
>         "document.getElementById('file-input').click(); " +
>         "var fileCont; " +
>         "var reader = new FileReader(); " +
>         "reader.onloadend = function(evt) { " +
>         "   if (evt.target.readyState == FileReader.DONE) { " +
>         "       fileCont = evt.target.result; " +
>         "   } " +
>         "   var arrayBuffer = this.result, " +
>         "     array = new Uint32Array(arrayBuffer), " +
>         "     binaryString = String.fromCharCode.apply(null, array); " +
>         "   Module.ccall('EM_gotOpenFileName', null,  ['string', 'string', 
> 'number'], [document.getElementById('file-input').value, binaryString, 
> arrayBuffer.byteLength]); " +
>         "}; " +
>         
> "reader.readAsArrayBuffer(document.getElementById('file-input').files[0]); "
>     ).c_str());
>
> Which then calls my C function where I do stuff with the file content:
> extern "C"
> {
>     EMSCRIPTEN_KEEPALIVE void EM_gotOpenFileName(char* fileName, char* 
> cont, int len)
>     {
>         // Store the file in a temporary location so we can read it later 
> if we need to.
>         // JavaScript doesn't allow us to grab it's location, so we must 
> do it this way.
>         std::string tempFile = fileName;
>
>         // Getting the file's name without any directories. i.e 
> "C:/fakepath/file.png" will turn into "file.png"
>         std::vector<std::string> tkns = findTokens("/", tempFile);
>         tempFile = tkns[tkns.size()-1];
>         tkns = Operations::findTokens("\\", tempFile);
>         tempFile = tkns[tkns.size()-1];
>         tempFile = (std::string)".temp/" + tempFile;
>
>         writeFile(tempFile, cont, len); // write the file. assume this 
> works fine using fwrite.
>
>         // ...
>     }
> }
>
> *What's (not) working:*
> Text files are writing correctly and being transferred with no problems.
> Binary files, such as images, are not. The data written looks different 
> than the actual file selected, though they have the same number of bytes.
> In JavaScript, I've tried using Uint8Array and Uint16Array. Uint32Array 
> errors "Invalid offset/length when creating typed array", and Uint64Array 
> doesn't exist.
>
> --
>
> Is there something I am doing wrong, or some other way I should read a 
> file (like an image's) contents?
> I need to be able to load the data (including binary data from an image) 
> into memory that I can do stuff with in C.
>
> 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].
For more options, visit https://groups.google.com/d/optout.

Reply via email to