从dllexported函数返回char *

时间:2014-06-13 13:33:47

标签: c++ c dllexport

我正在创建一个将被某些外部exe文件使用的DLL。其中一个暴露的功能是

...
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;
}

将在执行版本函数完成后处理local_copy变量(在这种情况下,返回的指针将指向一些随机数据)?如果是这样,返回指向const char *的指针的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

  

版本函数的调用者是否能够更改current_version变量的内容?

这是UB,因此实际行为取决于实施。调用者确实可以改变这个常数。在某些实现中,字符串文字存储在只读存储器中,因此尝试通过非const指针写入它会引发运行时错误。

  

将在执行版本函数完成

后处理local_copy变量

  

(在这种情况下返回的指针会指向一些随机数据)?

在大多数实现中,它将指向堆栈区域。写入它会破坏程序执行流程。

  

如果是这样,返回指向const char *的指针的最佳方法是什么?

在C ++中没有好办法。

答案 1 :(得分: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。这是我对具有内存问题的安全功能的最佳猜测。用户进行第一次呼叫以确定所需的长度。在调用函数中动态分配缓冲区,然后再次调用此方法。或者如果您已经知道缓冲区的大小和长度,则分配内存和分配长度,您只需要调用此函数一次。

答案 2 :(得分:0)

  1. 关于这些问题,我同意@Agent_L。

  2. 关于解决方案,我认为您可以使用静态字符数组作为缓冲区。如下:

  3. static char local_copy[64];
    static char current_version[] = "1.1";
    
    char *version() {
      strcpy(local_copy, current_version);
      return local_copy;
    }
    

    然后您无需担心处置local_copy