Как определить информацию о браузере из модуля WebAssembly?

Как инициировать переменную C ++ (скомпилированную в WebAssembly) из значения, обнаруженного с помощью JavaScript при запуске (например, current screen.availWidth)?

Этот код должен быть инициирован из модуля WebAssembly, поэтому пользователь не может ввести значение, отличное от реального.


person b26    schedule 17.01.2020    source источник
comment
@Dan Это вопрос C ++, поскольку он упоминается в самом объекте, почему вы продолжаете удалять тег C ++ и опускать вопрос? Webassembly может быть получен из ржавчины, чего мы здесь не хотим. Пожалуйста, посмотрите теги этого вопроса: stackoverflow.com/questions/20421002/   -  person b26    schedule 17.01.2020


Ответы (1)


Объяснение

Вы можете запустить код JavaScript изнутри своей функции C ++. Такой JS-код имеет доступ ко всем объектам, к которым вы обычно имеете доступ при запуске его в веб-браузере. Для этого мы будем использовать макрос EM_ASM_INT, который выполняет код JS, возвращая значение int.

Быстрое решение

Мы вводим код JS внутрь кода C ++ example.cpp. Использование функции int main() гарантирует, что код будет автоматически выполняться при загрузке страницы без необходимости загружать модуль WebAssembly вручную. Однако вы можете использовать другую функцию, экспортировать ее и также выполнять на своей веб-странице.

#include <iostream>
#include <emscripten.h>

int main()
{
   int screen_width = EM_ASM_INT(
       return screen.availWidth;);
   std::cout << "Screen width=" << screen_width << std::endl;
}

Мы компилируем приведенный выше example.cpp код с помощью компилятора Emscripten следующим образом:

emcc example.cpp -o example.html

Результатом является веб-страница со встроенной функцией int main() с JS-кодом внутри нее (действительно, начало). Чтобы запустить код, разрешив совместное использование ресурсов между разными источниками (CORS), мы будем использовать emrun (я не смог запустить пример в Firefox, поэтому вместо этого использовал Chrome):

emrun --browser chrome example.html

Комментарий

Этот подход работает для кода JS с возвращаемым значением типа скаляр int (с использованием EM_ASM_INT), doubleEM_ASM_DOUBLE), но также с массивом char* (с использованием EM_ASM_INT с осторожным и ручным управлением памятью, как показано здесь).

person quepas    schedule 28.02.2020
comment
Спасибо, я также только что обнаружил, что его также можно использовать для извлечения строк с помощью EM_ASM_INT. emscripten.org/docs/api_reference/ - person b26; 28.02.2020