我正在创建一个将被某些外部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 *的指针的最佳方法是什么?
答案 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)
关于这些问题,我同意@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
。