Войти
Unreal EngineФорумПрограммирование

UFunction, возвращающий FString

Страницы: 1 2 3 Следующая »
#0
(Правка: 13:48) 13:48, 21 июля 2021

Привет всем! Имеется метод

UFUNCTION() FString GetText()

При вызове оно падает, как я выяснил, потому, что анриловский рефлекшн берёт результат этой функции (который FString), преобразует его в указатель (FString*), а потом ещё и разыменовывает этот указатель, с закономерным результатом. Как я понял из этого, возвращать FString нельзя, можно возвращать только указатель на FString.

Хотелось бы увидеть комментарии от профи, правильно ли я понял суть, и почему это вообще так.

Заранее благодарен.


#1
(Правка: 13:53) 13:53, 21 июля 2021
как я выяснил

Как?

FString можно возвращать, никаких проблем с этим нет.
"Возвращать указатель" - это почти всегда не правильно. В UE по максимуму скрыта работа с ссырыми указателями.

#2
14:28, 21 июля 2021
Как?

Падает на строчке внутри с генерированного кода (который .gen.cpp)

*(FString*)Z_Param__Result=P_THIS->GetText();
Вызвано исключение по адресу 0x00007FFF57D1D777 (UE4Editor-Core.dll) в UE4Editor-Win64-DebugGame.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xFFFFFFFFFFFFFFFF.

Если P_THIS - указатель на экземпляр моего класса, то оно действительно работает неправильно.

Или я неверно трактую то, что происходит?

#3
14:41, 21 июля 2021

Kirwer7245
Ты где то вызываешь эту функцию? или ты её просто реализовал в С++ коде и всё. И она у тебя падает на ровном месте?

#4
(Правка: 16:38) 16:04, 21 июля 2021

1. Перепроверь, существует ли сущность T_THIS на момент вызова функции (особенно, если строка *(FString*)Z_Param__Result=P_THIS->GetText() вызывается из Tick)
2. Попробуй другую конструкцию:

UFUNCTION() void GetText(FString &str)
P_THIS->GetText(*(FString*)Z_Param__Result);

#5
(Правка: 13:39) 13:25, 22 июля 2021

тело функции в студию! или условия при которых она вызывается если это епиковская функция.
без него это гадание на кофейной гуще.
Но возвращать FString можно!
А вот возвращать указатель на FString в уфуншинах нельзя! указатели в уфуншине только на УОбжекты.
вобще возврат уфункшн если это не уобжект - это всегда значение. ни ссылка и не указатель.

#6
14:10, 22 июля 2021

gamedeveloper01
Я вызываю через рефлекшн:

auto paramsSize = func->ParmsSize;
auto paramBytes = byteArrayPool.Rent(paramsSize);
objPointer->ProcessEvent(func, paramsByte->Array);

objPointer указывает на валидный объект, func тоже, func->ParmsSize равен 12 байтам, полученный из пула массив имеет 16 байт (пробовал ставить другой пул с точными массивами, пробовал создавать массив а не брать из пула - бесполезно).

1. Перепроверь, существует ли сущность T_THIS на момент вызова функции (особенно, если строка *(FString*)Z_Param__Result=P_THIS->GetText() вызывается из Tick)

P_THIS это макрос, по факту это (SceneManagementUtils*)(Context), т.е. приведение некого указателя Context к указателю на объект моего класса (SceneManagementUtils).

Строка действительно вызывается из Tick. Соль в том, что сам метод отрабатывает, падение происходит при приравнивании результата вызова метода к *(FString*)Z_Param__Result.

UFUNCTION() void GetText(FString &str)
P_THIS->GetText(*(FString*)Z_Param__Result);

Отпишусь, как удастся. Мне надо понять как это провернуть через рефлекшн, ибо строчка с *(FString*)Z_Param__Result - это автосгенерированный код.

#7
14:13, 22 июля 2021

Sn_a_ke
> тело функции в студию! или условия при которых она вызывается если это
> епиковская функция.

UFUNCTION() FString GetText()
  {
    if (testIterationNumber++ % 2 == 0)
      return TEXT("A");
    else
      return TEXT("B");
  }

Функция специально написана для теста. Подозреваю, что ошибка где-то в другом месте, и я просто что-то повреждаю в памяти, а проявляется это не сразу, а здесь.

#8
14:15, 22 июля 2021

Kirwer7245
> auto paramsSize = func->ParmsSize;
> auto paramBytes = byteArrayPool.Rent(paramsSize);
> objPointer->ProcessEvent(func, paramsByte->Array);
Изображение

#9
(Правка: 14:25) 14:25, 22 июля 2021

Kirwer7245
> Я вызываю через рефлекшн:
так значит тут и проблема а не с функцией...
для начала утыкать свой код check-ассертами (на все некорректные условия)
а потом с отладчиком в воспроизвести крашь - и посмотреть что на самом деле происхдит

#10
(Правка: 17:03) 17:02, 22 июля 2021

Рекомендация от потомственного телепата: Что-то не так у тебя с временем жизни объекта. Если ты получаешь из FString сырую строку, эта сырая строка валидна лишь пока не удалился FString. Нельзя так просто строки туда-сюда преобразовывать по мере потребности.

#11
(Правка: 19:26) 19:25, 22 июля 2021

Поясните за уе, пожалуйста, на пальцах
Если я в ue4 делаю:

UFUNCTION(BlueprintPure, meta = (DisplayName = "Create Super Object", Keywords = "Create SuperObject", ShortTooltip = "Creates new SuperObject"), Category = "SuperObject")
static UMySuperObject* CreateSuperObject(const FString& _Name)
{
  UMySuperObject* obj = NewObject<UMySuperObject>();
  obj->Name = _Name;
  return obj;
}
уе контроллирует время жизни полученного объекта, или у меня течёт память?

#12
(Правка: 19:35) 19:34, 22 июля 2021

Контролирует.
Тут не плохо тема разобрана:
https://michaeljcole.github.io/wiki.unrealengine.com/Garbage_Coll… y_Allocation/

#13
19:39, 22 июля 2021

@!!ex
Спасибо!

#14
21:11, 22 июля 2021

meekobold
> уе контроллирует время жизни полученного объекта, или у меня течёт память?

если этот обьект не сохранить соответствующим образом - мусорщик его затрет довольно быстро.

с уобжектами утечкой памяти можно считать разве что забытую незатертую переменную где-нибудь...
во всем остальном не существует механизма получить утечку аналогичную с нативными плюсами.
Жизненный цикл  УОбжектов ближе к sharedpointer.

Страницы: 1 2 3 Следующая »
Unreal EngineФорумПрограммирование