Сегодня немного проверял Clone функции и набрёл на эту тему.
Хоть она старовата, но удивило это, и особенно то, что на это никто не отреагировал:
// Основной плагин
ArrayList aExample;
// any code
public int Native_Example(Plugin hPlugin, int args)
{
// native ArrayList nativeExample();
return view_as<int>(aExample.Clone());
}
// -------------------------
// Остальные плагины
public void OnMapStart()
{
// Получаем нужный нам ArrayList
ArrayList aCopy = nativeExample();
// any code
// Закрываем и высвобождаем память, если не нужен
delete aCopy;
}
Вот вам явное преимущество.
Есть шансы, что более правильно было сделать public any и return view_as<ArrayList>, но это фгня.
aExample.Clone() - владельцем Handle остался "Основной плагин".
"Остальные плагины" не могут его закрыть = утечка, т.к. "Основной плагин" его не закрывает.
Поэтому нужно делать:
return view_as<ArrayList>(CloneHandle(aExample, plugin));
Но и здесь могут быть проблемы, если вы надеетесь на то, что ваш оригинальный aExample массив не будет изменён.
Если важно сохранить целостность aExample, то правильно будет так:
public any MyNative_(Handle plugin, int args)
{
ArrayList hndl_clone = aExample.Clone();
ArrayList hndl_owner = view_as<ArrayList>(CloneHandle(hndl_clone, plugin));
delete hndl_clone;
return hndl_owner;
}
@Banana, хранить строки с вопросами/ответами более оптимизировано в StringMap, т.к. он не хранит в памяти весь размер буфера (как ArrayList), а хранит конкретно строку без лишнего размера. Ключом для StringMap может быть уникальный id вопросов/ответов.
int GetId()
{
static int i;
return ++i;
}
char sId[12];
[U]IntToString(GetId(), sId, sizeof(sId));
Ну и хранить вопросы с ответами можно так:
#define MAX_ANSWERS 2 // Максимум ответов на вопрос
ArrayList g_hAr; // Список вопросов и ответов
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
g_hAr = new ArrayList(MAX_ANSWERS + 1);
return APLRes_Success;
}
Первым в списке пусть будет id вопроса, а дальше ответы, 0 = нет ответа (или -1, смотри сам).