Я создаю DLL, которая будет использоваться каким-то внешним exe файлом. Одной из открытых функций является
...
char *current_version = "1.1";
...
extern "C" _declspec(dllexport) char* version(){
return current_version;
}
Поскольку текущая версия используется в нескольких местах, я создал переменную current_version. Позвонит ли вызывающий объект функции изменить содержимое переменной current_version? (Я надеюсь, он это сделает).
Если я изменю код на:
...
const char *current_version = "1.1"; //this is preferable
...
extern "C" _declspec(dllexport) char* version(){
char local_copy[100] = make_local_copy(current_version);
return *local_copy;
}
будет ли локальная переменная быть удалена после завершения выполнения функции версии (и в этом случае возвращаемый указатель укажет на некоторые случайные данные)? Если да, то каков наилучший способ вернуть указатель на const char *?
Позвонит ли вызывающий объект функции изменить содержимое переменной current_version?
Это UB, поэтому фактическое поведение зависит от реализации. Существует хорошая вероятность, что вызывающий абонент действительно может изменить эту константу. В некоторых реализациях строковые литералы хранятся в памяти только для чтения, поэтому попытка записи на него с помощью неконстантного указателя вместо этого выдает ошибку времени выполнения.
будет ли локальная переменная быть удалена после завершения выполнения функции версии
Да.
(и в этом случае возвращаемый указатель укажет на некоторые случайные данные)?
В большинстве реализаций он укажет на область стека. Запись на него приведет к повреждению потока выполнения программы.
Если да, то каков наилучший способ вернуть указатель на const char *?
В C++ нет хорошего способа сделать это.
Что касается вопросов, я согласен с @Agent_L.
Что касается решения, я думаю, вы можете использовать статический массив символов в качестве буфера. Точно так же:
static char local_copy[64];
static char current_version[] = "1.1";
char *version() {
strcpy(local_copy, current_version);
return local_copy;
}
Тогда вам не нужно беспокоиться об утилизации local_copy
.
extern "C" _declspec(dllexport) void version(char* buffer, int* len)
{
if (buffer == NULL || *len <= 0)
{
char local_copy[100] = make_local_copy(current_version);
*len = strlen (local_copy);
return;
}
char local_copy[100] = make_local_copy(current_version);
*len = strlen (local_copy);
strcpy_s(buffer, *len, local_copy);
return;
}
Это должно быть хорошей отправной точкой. Там могут быть ошибки, а также я рекомендую использовать wchar вместо char. Это мое лучшее предположение в безопасной функции с проблемами памяти. Пользователь делает первый вызов для определения требуемой длины. динамически выделять буфер в функции вызова, а затем снова вызвать этот метод. Или выделите память и назначьте длину, если вы уже знаете размер буфера и длину, вам нужно будет вызвать эту функцию только один раз.
char*
. Doextern "C" _declspec(dllexport) void version(char* buffer, int buffer_len){ strncpy(buffer, current_version, buffer_len); }