Ответ - да ... и нет ...
Если вам нужна поддержка старых браузеров (до Firefox 3), вы можете самостоятельно реализовать функцию NPN_PluginThreadAsyncCall. В Windows вы можете сделать это, создав структуру данных, которая может содержать указатель на функцию и непрозрачный указатель void *, а затем опубликовать пользовательское сообщение в главном окне с указателем на структуру данных как LPARAM.
Главное окно WINPPROC выполняется в потоке пользовательского интерфейса, который является потоком, который может общаться с Javascript. Поэтому, когда вы получаете это сообщение в своем WINPROC, вы просто приводите LPARAM обратно к указателю, вызываете метод с непрозрачными данными, а затем освобождаете структуру данных.
На Mac вы можете сделать то же самое с очередью для хранения событий, а затем с помощью события NULL (которое отправляется Mac OS при каждом тике) проверять, есть ли в нем что-либо. Если это так, отключите его, вызовите метод, освободите его и продолжайте.
Возможно, есть способ сделать это и в Linux, но я не знаю, что это такое.
Пример версии windows можно найти в проекте firebreath .
Обработка сообщения winproc находится в этом файле:
https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.cpp
Событие и структура данных определены в его заголовочном файле:
https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.h
И метод запуска этого события здесь:
void ActiveXBrowserHost::ScheduleAsyncCall(void (*func)(void *), void *userData)
{
if (m_hWnd != NULL)
::PostMessage(m_hWnd, WM_ASYNCTHREADINVOKE, NULL,
(LPARAM)new FB::WINDOWS_ASYNC_EVENT(func, userData));
}