Swig - C++ для JavaScript
Я пытаюсь построить простой модуль javascript, используя swig из моих файлов cpp. Я выполнил все правильные команды, но, похоже, ничего не работает. это мое .h
файл
#pragma once
class Die
{
public:
Die();
Die(int a);
~Die();
int foo(int a) ;
Die* getDie(int a);
int myVar;
};
мой .cpp
файл:
#include <iostream>
#include "example.h"
int Die::foo(int a) {
std::cout << "foo: running fact from simple_ex" <<std::endl;
return 1;
}
Die::Die(){}
Die::Die(int a){myVar = a;}
Die::~Die(){}
Die* Die::getDie(int a) {
return new Die (a);
}
мой .i
файл:
%module example
%{
#include "example.h"
%}
%include "example.h"
мой binding.gyp
файл:
{
"targets": [
{
"target_name": "example",
"sources": ["example.cpp", "example_wrap.cxx" ]
}
]
}
Я следовал всей команде от swig
Docs.
Я побежал:
sudo apt-get install libv8-dev
sudo apt-get install libjavascriptcoregtk-1.0-dev
swig -c++ -javascript -node example.i
node-gyp configure build
После запуска последних команд я получаю всевозможные ошибки:
error: ‘NewSymbol’ is not a member of ‘v8::String’
и многое, многое другое.. Любая помощь будет делать.
Спасибо!
1 ответ
Я попробовал этот пример, чтобы изучить этот интерфейс самостоятельно.
Чтобы помочь другим, кто может наткнуться на это, вот пример того, как работать с swig и js.
Сначала мы пишем класс C++ и его логику, используя объектно-ориентированный подход, который нас изучает swig.
#pragma once
class Die
{
public:
Die(int a);
~Die();
int foo(int a);
int myVar;
};
extern "C"
{
Die* getDie(int a);
}
Здесь интересно то, что мы не всегда создаем новый экземпляр, а используем внешнюю функцию, чтобы предоставить нам указатель на класс, который затем можно использовать для его импорта в наш Javascript. Это буквально то, что глоток все о.
Вот реализация:
#include <iostream>
#include "example.h"
int Die::foo(int a)
{
std::cout << "foo: running fact from simple_ex" << std::endl;
return 1;
}
Die::Die(int a)
{
myVar = a;
}
Die::~Die()
{
}
extern "C"
{
Die* getDie(int a)
{
return new Die(a);
}
}
также здесь функция для получения указанного указателя инкапсулирована в extern C, и именно так мы отделяем ее от реализации другого класса, а также некоторая помощь для компилятора.
Интерфейс swig такой же, как в вопросе. Он используется для создания swig-файла обертки, чтобы дать нам реализованный интерфейс между Javascript и нашей библиотекой C++.
%module example
%{
#include "example.h"
%}
%include "example.h"
это создает нам файл обертки, используя следующий оператор в терминале:
swig -c++ -javascript -node example.i
теперь нам нужны некоторые инструменты для Javascript, чтобы построить это:
вам нужно установить NodeJs и NPM, чтобы использовать следующие вещи.
сначала нам нужен файл package.json:
{
"name": "SwigJS",
"version": "0.0.1",
"scripts": {
"start": "node index.js",
"install": "node-gyp clean configure build"
},
"dependencies": {
"nan": "^2.16.0",
"node-gyp": "^9.0.0"
}
}
это важно, чтобы программа сборки знала некоторую информацию о пакете и его зависимостях.
после этого мы создаем файл с именем «binding.gyp»
{
"targets": [
{
"target_name": "SwigJS",
"sources": [ "example_wrap.cxx", "example.cpp" ],
"include_dirs" : [ "<!(node -e \"require('nan')\")" ]
}
]
}
это содержит информацию для нашей цели сборки, а также для nan.
чтобы это заработало, нам теперь нужно создать файл .node. это делается либо с помощью:
node-gyp configure
node-gyp build
или используя:
npm i
оба делают почти то же самое, как мне кажется. (поправьте меня, если я ошибаюсь)
наконец-то мы реализуем наш Javascript и используем там библиотеку. Есть еще несколько трюков, чтобы путь сверху исчез, чтобы вы могли написать просто require("modulname"), но на самом деле это слишком много для этого примера.
const Swigjs = require("./build/Release/SwigJS.node");
console.log("exports :", Swigjs); //show exports to see if we have a working library
die = Swigjs.getDie(5); //get the Class pointer
console.log("foo:" + die.foo(5)); //call a function from the class
Я надеюсь, что это поможет получить четкое представление о том, как swig и js работают вместе.