Поддержка пользовательских типов C++¶
Внимание
Эта документация все еще является экспериментальной, и детали могут быть изменены по мере итераций. Не стесняйтесь делиться своими отзывами в обсуждении внутри рабочей группы для этой страницы.
Более того, она содержит несколько ручных шагов. Пожалуйста, обратите внимание, что это не будет представлять окончательный опыт разработчиков, когда Новая архитектура станет стабильной. Мы работаем над инструментами, шаблонами и библиотеками, которые помогут вам быстро начать работу с новой архитектурой без необходимости проходить всю процедуру настройки.
По умолчанию C++ Turbo Native Modules поддерживает bridging functionality для большинства std:: стандартных типов.
Если вы хотите добавить поддержку новых / пользовательских типов в ваше приложение / библиотеку, вам нужно только предоставить необходимый заголовочный файл bridging.
Это руководство продолжает предыдущий раздел C++ Turbo Native Modules.
Пример: Int64¶
C++ Turbo Native Modules пока не поддерживает числа int64_t — потому что JavaScript не поддерживает числа больше 2^53.
Мы не можем представлять числа > 2^53 как JavaScript числа — но мы можем представлять их как JavaScript строки и автоматически преобразовывать (aka bridge) их в C++ int64_t, создав пользовательский заголовочный файл Bridging под названием Int64.h в папке tm:
| Int64.h | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
Ключевыми компонентами для вашего пользовательского заголовка bridging являются:
- Явная специализация структуры
Bridgingдля вашего пользовательского типа, в данном случаеint64_t. - Функция
fromJsдля преобразования типовjsi::в ваш пользовательский тип - Функция
toJSдля преобразования из вашего пользовательского типа в типыjsi:.
Если опустить fromJS или toJS, то вы сделаете бридинг заголовка либо readonly, либо writeonly.
Теперь вы можете добавить следующую функцию в вашу спецификацию JavaScript:
| NativeSampleModule.ts | |
|---|---|
1 2 3 | |
| NativeSampleModule.js | |
|---|---|
1 2 3 | |
Объявите его в файле NativeSampleModule.h и включите заголовочный файл Int64.h:
1 2 3 4 | |
И реализуйте его в NativeSampleModule.cpp:
1 2 3 4 5 6 | |
В своем приложении вы можете вызвать эту новую нативную функцию через:
1 2 3 4 5 6 | |
который должен вернуть 2097152.
Любой пользовательский тип¶
Аналогично приведенному выше примеру, теперь вы можете написать пользовательскую функциональность bridging для любого пользовательского типа C++, который вы хотите передать в react-native. Например, вы можете добавить поддержку folly::StringPiece, QString, boost::filesystem::path, absl::optional или любого другого типа, который вам нужно поддерживать в ваших C++ Turbo Native модулях.
| Path.h | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Пользовательские структуры¶
Вы можете использовать тот же подход для пользовательских типов в JavaScript, как, например, этот:
1 2 3 4 5 | |
который может быть открыт для вашего нативного модуля C++ Turbo через
| NativeSampleModule.ts | |
|---|---|
1 2 3 | |
| NativeSampleModule.js | |
|---|---|
1 2 3 | |
Ручная типизация¶
Чтобы использовать этот пользовательский тип в C++, вам нужно определить вашу пользовательскую Struct и bridging функцию, например, непосредственно в NativeSampleModule.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |
Объявите его в вашем файле NativeSampleModule.h:
1 | |
Реализуйте его в NativeSampleModule.cpp:
1 2 3 4 5 6 | |
В своем приложении вы можете вызвать эту новую нативную функцию через:
1 2 3 4 5 6 7 8 9 10 | |
который должен вернуть {"key": "1909", "enabled":false", "time":42}.
Это работает, но довольно сложно.
Struct generator¶
Codegen для нативных модулей C++ Turbo поддерживает генераторы структур, поэтому вы можете упростить приведенный выше код в NativeSampleModule.h до:
1 2 3 4 | |
С помощью использования CustomType вы объявляете имя для своей конкретной структуры.
Типы членов¶
С помощью std::string, bool, std::optional<int32_t> вы определяете типы свойств членов структуры в том порядке, в котором они были определены в вашей спецификации JavaScript. Порядок имеет значение. Аргумент 1-го шаблона относится к 1-му типу данных структуры, и так далее.
Без каких-либо пользовательских функций преобразования:
- вы можете только
bridgeJS string в std::string и JS boolean в bool. - Но вы можете выбирать различные JS
числапредставления в C++.
Базовый класс¶
NativeSampleModuleBaseCustomType — это автогенерируемый шаблон в вашем AppSpecsJSI.h, имя которого генерируется:
NativeSampleModule(имя нативного модуля C++ Turbo в спецификации JavaScript) +Base(константа) +CustomType(имя типа в спецификации JavaScript).
Та же схема именования применяется к необходимой структуре Bridging, которая определяется через struct Bridging<CustomType>.