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 <[email protected]> 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 <[email protected]> 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 <[email protected]>
>>> 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 [email protected].
>>>> 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 [email protected].
>>> 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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/emscripten-discuss/9a61817a-1871-4e43-a436-f7a958c04703n%40googlegroups.com.