【发布时间】:2018-01-05 07:24:03
【问题描述】:
我有一个 C++ DLL 函数,它接收一个 char * 并返回一个 char*。
DLL函数的定义是:
char * scanImage( char * fileDir){
string dir(fileDir);
string cvStr = cvScan(dir);
char * scanReturn = &cvStr[0];
cout << scanReturn << endl;
return (scanReturn);
}
客户端功能是:
int main()
{
char * ret;
ret = scanImage("files/stu2/1.bmp");
cout << ret << endl;
return 0;
}
现在DLL 函数 的cout 打印出正确的输出,这意味着参数正在传递而没有任何问题。但是 client function 的 cout 会打印出类似这样的内容-
我出于测试目的打印了 ret[i]。这总是在范围内返回 -35。还有strlen(ret) > strlen(scanReturn)。
我使用 std::string 而不是 char* 作为参数和返回值。那工作得很好。但我不能使用字符串(我想稍后将此 DLL 与 VB.NET 应用程序一起使用,字符串不适合那个,或者会?)。
现在如何解决这个问题?我正在使用 Visual C++ 在 Visual Studio 2017 IDE 中编译 DLL 和客户端程序。
更新:
char * scanImage( char * fileDir)
{
string dir(fileDir);
string cvStr = cvScan(dir);
char * scanReturn;
scanReturn = (char*)malloc(sizeof(char)* cvStr.size());
scanReturn = &cvStr[0];
cout << "DLL Output: " << endl << scanReturn << endl;
return (scanReturn);
}
为 scanReturn 动态分配内存。但我仍然遇到同样的问题。
【问题讨论】:
-
这是关于返回指向局部变量的指针的常见问题。一旦函数返回,变量
cvStr将超出范围,因此将被破坏并释放它处理的内存(您使用scanReturn指向的字符串)。这意味着scanReturn将指向不再存在的东西,取消引用该指针将导致未定义的行为。 -
有两种可能的解决方案:将指向缓冲区的指针(及其长度)作为参数传递给函数,然后将字符串复制到该函数。或者动态分配内存,让调用者释放它。
-
您必须 malloc 内存(就像您已经做的那样),将字符串的内容复制到其中(不要忘记 null 终止它),然后返回您从 malloc 获得的指针(不要将其分配给另一个地址,您的函数将泄漏!)。
-
只是一个快速提示 - 不要添加与您的问题没有直接关联的标签 - 例如 VB.Net 标签。您可能认为向更广泛的受众展示您的问题是件好事,但是绝大多数 VB 人员对 c++ 一无所知。干杯
-
@DidierTrosset :因为他计划稍后在 VB.NET 中 P/Invoking 这个,在这种情况下,他需要一个可以编组为 .NET 类型的返回类型 (
char*-> @987654330 @)。