reckfellENGINE

Первое нативное расширение Windows x64

Собрать DLL, проверить класс, константы и выгрузку.

На этой странице

Пример рассчитан на Windows x64, Reckfell 1.0.0 и MSVC с инструментами C++. Он регистрирует абстрактный DocsNativeProbe : Entity, ProductVersion=10000 и EntityPathVariant=22. Создать такой класс как персонажа нельзя: это проверка сборки и ABI.

1. Подготовьте исходник и дескриптор

Создайте отдельный тестовый проект. Сохраните native_probe.cpp и native_probe.reckfellextension:

C++
#include "reckfellextension_interface.h"

// This example is deliberately Windows x64 only, not a general C++ binding.
struct NativeStringName { void *opaque; };
static_assert(sizeof(NativeStringName) == 8, "Check StringName size against extension_api.json");
static_assert(RECKFELLEXTENSION_VARIANT_TYPE_ENTITY_PATH == 22, "Unexpected EntityPath ABI");

static ReckfellExtensionClassLibraryPtr library;
static ReckfellExtensionInterfaceStringNameNewWithUtf8Chars name_new;
static ReckfellExtensionPtrDestructor name_destroy;
static ReckfellExtensionInterfaceClassdbRegisterExtensionClass6 register_class;
static ReckfellExtensionInterfaceClassdbUnregisterExtensionClass unregister_class;
static ReckfellExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant register_constant;

static void free_instance(void *, ReckfellExtensionClassInstancePtr) {}
static void initialize(void *, ReckfellExtensionInitializationLevel level) {
    if (level != RECKFELLEXTENSION_INITIALIZATION_SCENE) return;
    NativeStringName name, parent, enum_name, constant;
    name_new(&name, "DocsNativeProbe");
    name_new(&parent, "Entity");
    name_new(&enum_name, "");
    ReckfellExtensionClassCreationInfo6 info = {};
    info.is_abstract = 1;
    info.is_exposed = 1;
    info.free_instance_func = free_instance;
    register_class(library, &name, &parent, &info);
    name_new(&constant, "ProductVersion");
    register_constant(library, &name, &enum_name, &constant, 10000, 0);
    name_destroy(&constant);
    name_new(&constant, "EntityPathVariant");
    register_constant(library, &name, &enum_name, &constant, 22, 0);
    name_destroy(&constant);
    name_destroy(&enum_name);
    name_destroy(&parent);
    name_destroy(&name);
}
static void deinitialize(void *, ReckfellExtensionInitializationLevel level) {
    if (level != RECKFELLEXTENSION_INITIALIZATION_SCENE) return;
    NativeStringName name;
    name_new(&name, "DocsNativeProbe");
    unregister_class(library, &name);
    name_destroy(&name);
}
extern "C" __declspec(dllexport) ReckfellExtensionBool reckfell_docs_init(
    ReckfellExtensionInterfaceGetProcAddress get_proc,
    ReckfellExtensionClassLibraryPtr native_library,
    ReckfellExtensionInitialization *initialization) {
    library = native_library;
    name_new = (ReckfellExtensionInterfaceStringNameNewWithUtf8Chars)get_proc("string_name_new_with_utf8_chars");
    register_class = (ReckfellExtensionInterfaceClassdbRegisterExtensionClass6)get_proc("classdb_register_extension_class6");
    unregister_class = (ReckfellExtensionInterfaceClassdbUnregisterExtensionClass)get_proc("classdb_unregister_extension_class");
    register_constant = (ReckfellExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant)get_proc("classdb_register_extension_class_integer_constant");
    auto get_destructor = (ReckfellExtensionInterfaceVariantGetPtrDestructor)get_proc("variant_get_ptr_destructor");
    if (!name_new || !register_class || !unregister_class || !register_constant || !get_destructor) return 0;
    name_destroy = get_destructor(RECKFELLEXTENSION_VARIANT_TYPE_STRING_NAME);
    if (!name_destroy) return 0;
    initialization->minimum_initialization_level = RECKFELLEXTENSION_INITIALIZATION_SCENE;
    initialization->userdata = nullptr;
    initialization->initialize = initialize;
    initialization->deinitialize = deinitialize;
    return 1;
}
Конфигурация
[configuration]
entry_symbol = "reckfell_docs_init"
compatibility_minimum = "1.0.0"
reloadable = false

[libraries]
windows.x86_64 = "./native_probe.windows.x86_64.dll"

extern "C" сохраняет имя reckfell_docs_init; оно должно совпадать с entry_symbol. Если обязательная функция get_proc отсутствует, инициализация возвращает 0 вместо вызова пустого указателя. Размер буфера StringName 8 байт выбран только для проверенного Windows x64; ABI и время жизни.

2. Соберите DLL

Откройте x64 Developer PowerShell для MSVC. Перейдите в каталог исходника, задайте $Sdk абсолютным путём к установленному ExtensionSDK и выполните:

PowerShell
cl /nologo /std:c++17 /EHsc /LD /W3 /WX /I"$Sdk/include" native_probe.cpp /Fe:native_probe.windows.x86_64.dll

Проверьте код завершения. Нужный результат — native_probe.windows.x86_64.dll; .lib, .exp и .obj не являются загружаемой библиотекой. Другие проверенные сборщики: CMake, SCons.

3. Проверьте загрузку

Положите DLL и дескриптор рядом в asset://addons/native_probe/. Путь ./native_probe.windows.x86_64.dll считается относительно дескриптора. ОС и архитектура должны совпадать; переименование файла не исправляет другую архитектуру DLL.

В C# вызовите ReckfellExtensionManager.LoadExtension("asset://addons/native_probe/native_probe.reckfellextension") и проверьте LoadStatus.Ok. Затем ClassDB.ClassExists("DocsNativeProbe") должно быть true, а ClassDB.ClassGetIntegerConstant("DocsNativeProbe", "ProductVersion") — 10000. Автоматическое обнаружение проектом выполняет сканирование редактора; действия мышью здесь не проверялись.

Повторная загрузка того же пути дала AlreadyLoaded. После UnloadExtension() класс и путь исчезли из реестров. Не заменяйте DLL, используемую запущенным процессом. Пример отключает горячую перезагрузку через reloadable=false.

Если не работает

Файл не найден — проверьте оба пути. Точка входа отсутствует — проверьте экспорт, extern "C" и entry_symbol. Библиотека не открывается — проверьте архитектуру и зависимости среды выполнения. Инициализация отказала — сверяйте обязательные функции и версию SDK. Класс зарегистрирован, создать нельзя — ожидаемо, он абстрактный.

Все три сборки загрузились, передали константы через ABI и выгрузились. Создаваемые native-instance объекты, другие платформы и перезагрузка живых объектов не проверялись. Изменять или пересобирать движок не требуется.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.