2015-03-29 3 views
1

Я пытаюсь использовать Emscripten для превращения библиотеки C в переносимый модуль JavaScript, который будет загружен AMD (например, Require.JS) и обеспечит доступ к его функциям и вещам:Emscripten с модульными загрузчиками

require("vendor/mylib.js", function(mylib) { 
    mylib.function1(); 
}); 

Однако, я видел, что Emscripten загрязняет глобальное пространство имен множеством переменных, что противоречит предположению, что модули должны быть независимыми и не сталкиваться с другими загруженными модулями.

Вопрос в следующем: Каков наилучший способ использования Emscrpiten с AMD?

Есть ли способ, которым я могу сказать Emscripten, чтобы не просачивать ничего в global?

ответ

4

Есть 2 варианта командной строки от emcc docs, которые могут помочь, --pre-js <file> и --post-js <file>. Они позволяют вам сгенерировать сгенерированный код, и поэтому вы можете интегрироваться с AMD.

Например, вы могли бы иметь префикс файл

// prefix.js 
define(function() { 
    return function(Module) { 

и постфикс файл

// postfix.js 
    }; 
}); 

который вы обобщите выводящий к myModule.js используя что-то вроде

emcc --pre-js prefix.js --post-js postfix.js -o myModule.js myModule.cpp 

а затем require модуль, используя синтаксис RequireJS:

require(['myModule'], function(myModule) { 
    myModule({... Module definition object ...}); 
}); 

Более полный пример, устанавливающий элемент холста в объекте определения модуля. Я также включаю domReady plugin, чтобы иметь возможность захватывать элементы, когда DOM готов.

<!DOCTYPE html> 
<html> 
    <head> 
    <script src="require.js"></script> 
    <script> 
     require(['domReady', 'myModule'], function(domReady, myModule) { 
     domReady(function() { 
      myModule({ 
      canvas: document.getElementById('canvas_1') 
      }); 
      myModule({ 
      canvas: document.getElementById('canvas_2') 
      }); 
     }); 
     }); 
    </script> 
    </head> 
    <body> 
    <canvas id="canvas_1"></canvas> 
    <canvas id="canvas_2"></canvas> 
    </body> 
</html> 

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

Вышеупомянутая HTML-страница видна с http://plnkr.co/edit/8jE3uLwrlszQuHbixU68?p=preview. Он загружает программу на C++:

#include <iostream> 
using std::cerr; 

int main() { 
    cerr << "In C++ main function"; 
} 

При загрузке Plunker, то вы должны видеть «в основной функции C++» в два раза, один раз для каждого загруженного модуля.

Если вам нужен доступ к объекту модуля с изменениями, внесенными Emscripten, скажем, назвать открытые библиотечные функции, вы можете сделать что-то вроде следующего, ожидая всех зависимостей, которые сама Emscripten нагрузки, используя monitorRunDependencies вариант:

require(['myModule'], function(myModule) { 
    var moduleDef = { 
    monitorRunDependencies: function(numberOfDependenciesRemaining) { 
     if (numberOfDependenciesRemaining) return; 
     // At this point we can call functions added to moduleDef 
     // such as cwrap or ccall 
    } 
    } 
    myModule(moduleDef); 
}); 
+0

Очень интересно, не думал об использовании '-pre-js' и' -post-js' вместе так ... Но я проверял, что Plunk и объект 'Module' присутствуют в глобальном пространстве имен. Как я могу избежать этого? –

+0

@jmendeth Я подозреваю, что создал его, используя устаревшую версию Emscripten. Последние версии, которые включают фиксацию на https://github.com/kripken/emscripten/commit/746230f45557868a91741553bf12cb17a3a95628 Я думаю, что не будет помещать объект 'Module' в глобальное пространство имен –

+0

Oh. Тогда время для обновления моего emscripten! Благодаря! –

 Смежные вопросы

  • Нет связанных вопросов^_^