2015-03-29 4 views
0

Я хотел бы создать std::vector (в частности, std::vector<string>) в C++, а затем передать его (или, вернее, указатель на него) на Javascript, чтобы иметь возможность доступа к своим данным/функциям из непосредственно написанного Javascript.Передать указатель на std :: вектор на Javascript, используя Emscripten, и использовать его

До сих пор я могу получить целочисленный указатель:

vector<string> myVector; 
myVector.push_back("First item"); 
myVector.push_back("Second item"); 

EM_ASM_ARGS({ 
    // Prints out an integer value of the pointer, 
    // but I would like to access the object members/data 
    // of myVector 
    console.log($0); 
}, &myVector); 

я нашел информацию на http://kripken.github.io/emscripten-site/docs/api_reference/bind.h.html#register_vector__cCP и http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#built-in-type-conversions о функции register_vector

#include <emscripten/bind.h> 
EMSCRIPTEN_BINDINGS(Wrappers) { 
    register_vector<std::string>("VectorString"); 
}; 

, которые могут быть использованы для создания нового вектора из Javascript world:

var myVector = new Module.VectorString(); 

, но я не могу понять, как использовать это для доступа к вектору, который уже существует в мире C++.

Если я пытаюсь использовать Module.Runtime.dynCall('v', $0, []); на указатель, как в https://stackoverflow.com/a/29319440/1319998 при прохождении указателей на функции, то я получаю сообщение об ошибке:

Invalid function pointer '380' called with signature 'v'

Я пытался несколько различных комбинаций подписей, и все они похоже, не работает (что меня не очень удивляет: на самом деле это не указатель функции, который я вызываю, но указатель на экземпляр объекта)

+0

Я редактировал этот вопрос, чтобы объяснить, почему это не дубликат http://stackoverflow.com/a/29319440/1319998. Решение в этом случае не применяется: это вызывало указатель на функцию C++ из Javascript, в то время как этот вопрос касается доступа к членам существующего объекта C++. –

+0

Я также отредактировал название на http://stackoverflow.com/a/29319440/1319998 (это мой вопрос), надеюсь, лучше показать, почему это другое. –

ответ

3

Использование reinterpret_cast трюка от https://stackoverflow.com/a/27364643/1319998 вы можете добавить еще один конструктор в объект вернулся из register_vector завода, который не делает ничего, но преобразует целое указатель на vector<string>:

vector<string> *vectorFromIntPointer(uintptr_t vec) { 
    return reinterpret_cast<vector<string> *>(vec); 
} 

EMSCRIPTEN_BINDINGS(Wrappers) { 
    register_vector<string>("VectorString").constructor(&vectorFromIntPointer, allow_raw_pointers()); 
}; 

Затем, если вы создаете вектор в коде C++, вы можете получить доступ в JS коде

  • Получение указателя чтобы он
  • Передача указателя на JS кода с помощью EM_AMS_ARGS
  • в JS кодекс, создать новый объект Module.VectorString проходящее в значении указателя конструктору

Как показано в следующем коде:

vector<string> myVector; 
myVector.push_back("First item"); 
myVector.push_back("Second item"); 

EM_ASM_ARGS({ 
    var myVector = new Module.VectorString($0); 
    // Prints "Second item" 
    console.log(myVector.get(1)); 
}, &myVector); 
+0

Где находится документация для функции * .get *, как вы нашли эту функцию для myVector? Пожалуйста, разместите ссылку thnx. –