Поддержка пользовательских типов 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-му типу данных структуры, и так далее.
Без каких-либо пользовательских функций преобразования:
- вы можете только
bridge
JS string в std::string и JS boolean в bool. - Но вы можете выбирать различные JS
числа
представления в C++.
Базовый класс¶
NativeSampleModuleBaseCustomType
— это автогенерируемый шаблон в вашем AppSpecsJSI.h
, имя которого генерируется:
NativeSampleModule
(имя нативного модуля C++ Turbo в спецификации JavaScript) +Base
(константа) +CustomType
(имя типа в спецификации JavaScript).
Та же схема именования применяется к необходимой структуре Bridging
, которая определяется через struct Bridging<CustomType>
.