I think I figured it out. It looked like the file content was copied to the wasm memory with this:
void Test::read() { auto onFileReady = [=](const QString &fileName, const QByteArray & fileContents) { if (fileName.isEmpty()) { // Report error1 } else { std::string aFileName = "/home/user/" + fileName.toStdString(); EM_ASM({ FS.writeFile(UTF8ToString($0), new Uint8Array(Module.HEAPU8. buffer, $1, $2)); }, aFileName.c_str(), fileContents.data(), fileContents.size()); } }; QFileDialog::getOpenFileContent("*.*", onFileReady); } But I am still not sure, that it is correct, even if it is worked somehow: EM_ASM({ FS.writeFile(UTF8ToString($0), new Uint8Array(Module.HEAPU8. buffer, $1, $2)); }, aFileName.c_str(), fileContents.data(), fileContents.size()); Best, Balázs On Monday, October 17, 2022 at 11:29:13 AM UTC+2 Balázs Varga wrote: > Hi! > > I would have a question about the FS.writeFile function. > > I tried to use is in c++ similar like this: > https://github.com/emscripten-core/emscripten/issues/17230 > > But didn't worked for me with this: > > void Test::read() > { > auto onFileReady = [=](const QString &fileName, const QByteArray > &fileContents) { > if (fileName.isEmpty()) { > // Report error1 > } else { > emscripten::val fileContentView = > emscripten::val(emscripten::typed_memory_view(fileContents.size(), > fileContents.constData())); > emscripten::val fileContentCopy = > emscripten::val::global("ArrayBuffer").new_(fileContents.size()); > emscripten::val fileContentCopyView = > emscripten::val::global("Uint8Array").new_(fileContentCopy); > fileContentCopyView.call<void>("set", fileContentView); > //emscripten::val contentArray = emscripten::val::array(); > //contentArray.call<void>("push", fileContentCopyView); > std::string path = fileName.toStdString(); > EM_ASM({ > FS.writeFile(path, new Uint8Array([ 1, 2, 3, 4 ])); > }); > } > }; > > QFileDialog::getOpenFileContent("*.*", onFileReady); > } > > If I tried to use a variable like 'path' in the example, it didn't work. > EM_ASM({ > FS.writeFile(path, new Uint8Array([ 1, 2, 3, 4 ])); > }); > > But If I used like this, it works: > EM_ASM({ > FS.writeFile("/write_file.txt", new Uint8Array([ 1, 2, 3, 4 ])); > }); > > So my question is, how can I use a variable inside the EM_ASM({ }) ? > Furthermore, how can I convert a char* to Uint8Array for the FS.writeFile() > function? I tried a lot of ways (like in the example with emscripten::val) > but it didn't work. > > Thanks for the help in advance. > > All the best, > Balázs > > Balázs Varga <balazs....@gmail.com> ezt írta (időpont: 2022. okt. 14., P, > 12:23): > >> Thanks for getting back to me. :) Yes, the code is a c++ and not a JS >> library, so MAIN_THREAD_EM_ASM can be useful. But I have no idea yet how to >> make it work with that. >> >> Best, >> Balázs >> >> 'Sam Clegg' via emscripten-discuss <emscripte...@googlegroups.com> ezt >> írta (időpont: 2022. okt. 13., Cs, 18:35): >> >>> It looks like that API only works on the main thread (since it uses the >>> DOM). >>> >>> If you really need to call such APIs on a background thread there are >>> various ways to proxy the work back to the main thread. See >>> https://emscripten.org/docs/porting/pthreads.html#proxying. If the >>> code in question is not a JS library (e.g. if its written in EM_JS or >>> EM_ASM) you can use `MAIN_THREAD_EM_ASM` and/or >>> `emscripten_sync_run_in_main_thread` helpers. >>> >>> cheers, >>> sam >>> >>> >>> On Thu, Oct 13, 2022 at 8:31 AM Balázs Varga <balazs....@gmail.com> >>> wrote: >>> >>>> Hi! >>>> >>>> I run into a problem with >>>> QFileDialog::getOpenFileContent function, which are use to access to >>>> the local filesystem with emscripten: >>>> https://doc.qt.io/qt-5/qfiledialog.html#getOpenFileContent >>>> >>>> I tried to call it on a different thread then what on the wasm >>>> application is running: >>>> std::thread th1 (QFileDialog::getOpenFileContent, "*.*", onFileReady); >>>> th1.join(); >>>> >>>> But in that case, it froze at the emscripten part in the openFileDialog >>>> function and no file dialogue was opened. >>>> emscripten::val document = emscripten::val::global("document"); >>>> emscripten::val input = document.call<emscripten::val>("createElement", >>>> std::string("input")); >>>> >>>> >>>> *I got the error message at creating the input value.* >>>> >>>> *https://codereview.qt-project.org/c/qt/qtbase/+/250461/7/src/gui/platform/wasm/qwasmlocalfileaccess.cpp#129* >>>> >>>> <https://codereview.qt-project.org/c/qt/qtbase/+/250461/7/src/gui/platform/wasm/qwasmlocalfileaccess.cpp#129> >>>> >>>> Running on the main thread there is no error and works fine. >>>> Any idea what could be the problem/solution here? >>>> I got this error message: >>>> >>>> worker.js onmessage() captured an uncaught exception: TypeError: Cannot >>>> read properties of undefined (reading 'createElement') >>>> self.onmessage @ soffice.worker.js:207 >>>> soffice.worker.js:208 TypeError: Cannot read properties of undefined >>>> (reading 'createElement') >>>> at methodCaller_emscripten$$val_$std$$string$ (eval at new_ >>>> (47933e67-c694-46fe-af70-91dc8b50859c:8694:27), <anonymous>:5:20) >>>> at __emval_call_method >>>> (47933e67-c694-46fe-af70-91dc8b50859c:9267:14) >>>> at emscripten::internal::MethodCaller<emscripten::val, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> > >::call(emscripten::internal::_EM_VAL*, char >>>> const*, std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >>>> emscripten::internal::MethodCaller<emscripten::val, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> > >::call(emscripten::internal::_EM_VAL*, char >>>> const*, std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >&&) (val.h:278) >>>> at emscripten::val emscripten::val::call<emscripten::val, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> > >(char const*, std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> >&&) >>>> emscripten::val >>>> emscripten::val::call<emscripten::val, std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > >(char const*, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >&&) const (val.h:498) >>>> at >>>> QWasmLocalFileAccess::openFileDialog(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> QWasmLocalFileAccess::FileSelectMode, std::__2::function<void >>>> (qstdweb::FileList const&)> >>>> QWasmLocalFileAccess::openFileDialog(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> QWasmLocalFileAccess::FileSelectMode, std::__2::function<void >>>> (qstdweb::FileList const&)> const&) (qwasmlocalfileaccess.cpp:131) >>>> at QWasmLocalFileAccess::openFiles(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> QWasmLocalFileAccess::FileSelectMode, std::__2::function<void (int)> >>>> const&, std::__2::function<char* (unsigned long long, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >)> const&, std::__2::function<void ()> >>>> QWasmLocalFileAccess::openFiles(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> QWasmLocalFileAccess::FileSelectMode, std::__2::function<void (int)> >>>> const&, std::__2::function<char* (unsigned long long, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >)> const&, std::__2::function<void ()> const&) >>>> (qwasmlocalfileaccess.cpp:156) >>>> at QWasmLocalFileAccess::openFile(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> std::__2::function<void (bool)> const&, std::__2::function<char* (unsigned >>>> long long, std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >)> const&, std::__2::function<void ()> >>>> QWasmLocalFileAccess::openFile(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> std::__2::function<void (bool)> const&, std::__2::function<char* (unsigned >>>> long long, std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >)> const&, std::__2::function<void ()> const&) >>>> (qwasmlocalfileaccess.cpp:169) >>>> at QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> QFileDialog::getOpenFileContent(QString const&, std::__2::function<void >>>> (QString const&, QByteArray const&)> const&)::$_2::operator()() >>>> (qfiledialog.cpp:2444) >>>> at >>>> decltype(std::__2::forward<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(fp)()) >>>> std::__2::__invoke<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> decltype(std::__2::forward<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(fp)()) >>>> std::__2::__invoke<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&) >>>> (type_traits:3694) >>>> at void std::__2::__invoke_void_return_wrapper<void, >>>> true>::__call<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> void >>>> std::__2::__invoke_void_return_wrapper<void, >>>> true>::__call<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&) >>>> (__functional_base:348)worker.js onmessage() captured an uncaught >>>> exception: TypeError: Cannot read properties of undefined (reading >>>> 'createElement') >>>> self.onmessage @ soffice.worker.js:207 >>>> soffice.worker.js:208 TypeError: Cannot read properties of undefined >>>> (reading 'createElement') >>>> at methodCaller_emscripten$$val_$std$$string$ (eval at new_ >>>> (47933e67-c694-46fe-af70-91dc8b50859c:8694:27), <anonymous>:5:20) >>>> at __emval_call_method >>>> (47933e67-c694-46fe-af70-91dc8b50859c:9267:14) >>>> at emscripten::internal::MethodCaller<emscripten::val, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> > >::call(emscripten::internal::_EM_VAL*, char >>>> const*, std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >>>> emscripten::internal::MethodCaller<emscripten::val, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> > >::call(emscripten::internal::_EM_VAL*, char >>>> const*, std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >&&) (val.h:278) >>>> at emscripten::val emscripten::val::call<emscripten::val, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> > >(char const*, std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> >&&) >>>> emscripten::val >>>> emscripten::val::call<emscripten::val, std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > >(char const*, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >&&) const (val.h:498) >>>> at >>>> QWasmLocalFileAccess::openFileDialog(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> QWasmLocalFileAccess::FileSelectMode, std::__2::function<void >>>> (qstdweb::FileList const&)> >>>> QWasmLocalFileAccess::openFileDialog(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> QWasmLocalFileAccess::FileSelectMode, std::__2::function<void >>>> (qstdweb::FileList const&)> const&) (qwasmlocalfileaccess.cpp:131) >>>> at QWasmLocalFileAccess::openFiles(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> QWasmLocalFileAccess::FileSelectMode, std::__2::function<void (int)> >>>> const&, std::__2::function<char* (unsigned long long, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >)> const&, std::__2::function<void ()> >>>> QWasmLocalFileAccess::openFiles(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> QWasmLocalFileAccess::FileSelectMode, std::__2::function<void (int)> >>>> const&, std::__2::function<char* (unsigned long long, >>>> std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >)> const&, std::__2::function<void ()> const&) >>>> (qwasmlocalfileaccess.cpp:156) >>>> at QWasmLocalFileAccess::openFile(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> std::__2::function<void (bool)> const&, std::__2::function<char* (unsigned >>>> long long, std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >)> const&, std::__2::function<void ()> >>>> QWasmLocalFileAccess::openFile(std::__2::basic_string<char, >>>> std::__2::char_traits<char>, std::__2::allocator<char> > const&, >>>> std::__2::function<void (bool)> const&, std::__2::function<char* (unsigned >>>> long long, std::__2::basic_string<char, std::__2::char_traits<char>, >>>> std::__2::allocator<char> >)> const&, std::__2::function<void ()> const&) >>>> (qwasmlocalfileaccess.cpp:169) >>>> at QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> QFileDialog::getOpenFileContent(QString const&, std::__2::function<void >>>> (QString const&, QByteArray const&)> const&)::$_2::operator()() >>>> (qfiledialog.cpp:2444) >>>> at >>>> decltype(std::__2::forward<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(fp)()) >>>> std::__2::__invoke<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> decltype(std::__2::forward<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(fp)()) >>>> std::__2::__invoke<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&) >>>> (type_traits:3694) >>>> at void std::__2::__invoke_void_return_wrapper<void, >>>> true>::__call<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> void >>>> std::__2::__invoke_void_return_wrapper<void, >>>> true>::__call<QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&>(QFileDialog::getOpenFileContent(QString const&, >>>> std::__2::function<void (QString const&, QByteArray const&)> >>>> const&)::$_2&) >>>> (__functional_base:348) >>>> >>>> Thanks in advance, >>>> Balazs >>>> >>>> -- >>>> 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/0b5c70fa-8cd2-4705-a64c-4816c1189dccn%40googlegroups.com >>>> >>>> <https://groups.google.com/d/msgid/emscripten-discuss/0b5c70fa-8cd2-4705-a64c-4816c1189dccn%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> -- >>> 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/CAL_va29QkPT_WVX_fsj1qe8keQ_serFRrgF72kmYtMshw7N2dA%40mail.gmail.com >>> >>> <https://groups.google.com/d/msgid/emscripten-discuss/CAL_va29QkPT_WVX_fsj1qe8keQ_serFRrgF72kmYtMshw7N2dA%40mail.gmail.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- 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-discuss+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/9a61817a-1871-4e43-a436-f7a958c04703n%40googlegroups.com.