Возвращение char * из функции dllexported

0

Я создаю 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 *?

  • 0
    что делает make_local_copy? мелкая копия или глубокая копия?
  • 1
    Как правило, вы всегда должны избегать возврата char* . Do extern "C" _declspec(dllexport) void version(char* buffer, int buffer_len){ strncpy(buffer, current_version, buffer_len); }
Показать ещё 2 комментария
Теги:
dllexport

3 ответа

2
Лучший ответ

Позвонит ли вызывающий объект функции изменить содержимое переменной current_version?

Это UB, поэтому фактическое поведение зависит от реализации. Существует хорошая вероятность, что вызывающий абонент действительно может изменить эту константу. В некоторых реализациях строковые литералы хранятся в памяти только для чтения, поэтому попытка записи на него с помощью неконстантного указателя вместо этого выдает ошибку времени выполнения.

будет ли локальная переменная быть удалена после завершения выполнения функции версии

Да.

(и в этом случае возвращаемый указатель укажет на некоторые случайные данные)?

В большинстве реализаций он укажет на область стека. Запись на него приведет к повреждению потока выполнения программы.

Если да, то каков наилучший способ вернуть указатель на const char *?

В C++ нет хорошего способа сделать это.

0
  1. Что касается вопросов, я согласен с @Agent_L.

  2. Что касается решения, я думаю, вы можете использовать статический массив символов в качестве буфера. Точно так же:

static char local_copy[64];
static char current_version[] = "1.1";

char *version() {
  strcpy(local_copy, current_version);
  return local_copy;
}

Тогда вам не нужно беспокоиться об утилизации local_copy.

  • 0
    Согласитесь, но при условии, что у меня будет 20 переменных (app_name, kernel_version, ...), это приведет к большему количеству переменных.
0
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. Это мое лучшее предположение в безопасной функции с проблемами памяти. Пользователь делает первый вызов для определения требуемой длины. динамически выделять буфер в функции вызова, а затем снова вызвать этот метод. Или выделите память и назначьте длину, если вы уже знаете размер буфера и длину, вам нужно будет вызвать эту функцию только один раз.

  • 0
    Почему вы делаете локальную копию константы? Тебе это не нужно.
  • 0
    Я согласен, я не уверен, почему у @orwe есть это в его коде. Я подумал, что это какая-то ключевая часть логики, в которой он нуждался, поэтому я не касался этой части.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню