无效从'const void *'转换为'PVOID {aka void *}'[-fpermissive]

时间:2013-10-31 07:35:44

标签: c++ strlen gpib

我正在编写一个程序(好吧......使用Tektronix的示例代码)来测试通过网络与我们实验室频谱分析仪的信息交换。

提供了名为“decl-32.h”的头文件,示例代码中包含以下行,以及它产生的错误:

ibwrt(GpibDevice,“SYSTem:ERRor:ALL?”,strlen(“SYSTem:ERRor:ALL?”));

“从'const void *'无效转换为'PVOID {aka void *}'[-fpermissive]”

在头文件中,以下代码行突出显示为错误,以及以下错误:

extern int __stdcall ibwrt(int ud,PVOID buf,long cnt);

“初始化'int ibwrt(int,PVOID,long int)'的参数2'[-fpermissive]”

问题在于我不熟悉这种复杂的变量定义,用法和转换。

有人可以给我一些建议吗?我相信这对于那些不熟悉这种变量类型和转换等的其他人来说是相关的。

提前谢谢!

2 个答案:

答案 0 :(得分:2)

ibwrt的第二个参数是PVOID,它是void*的typedef。在C ++中,指针类型可以隐式转换为void*,但是,与所有其他类型一样,转换不允许丢弃一个qulifier。也就是说,从const char*(类型字符串文字衰减到)转换为void*是非法的。因此错误。

在C语言中,代码来自哪里,字符串文字衰减到char*,你的行将按原样编译。原因是历史 - C的早期实现没有const关键字。

要解决此问题,您可以使用const投射const_cast

const char* s = "SYSTem:ERRor:ALL?";
ibwrt(GpibDevice, const_cast<char*>(s), strlen("SYSTem:ERRor:ALL?"));

您需要信任它不会尝试通过传递它的指针修改字符串文字的函数,否则它将调用未定义的行为。在这种情况下似乎是一个安全的假设(或者可能不是,参数名为buf,请注意!),但如果你想确定,请在答案中显示像@MikeSeymour这样的字符串副本。

答案 1 :(得分:1)

问题是字符串文字是不可变的,而且这个函数需要一个非const指向数据的指针。

如果保证函数不修改数据,并且缺少const只是一个疏忽,那么你可以转换为所需的类型:

ibwrt(GpibDevice, const_cast<char*>("SYSTem:ERRor:ALL?"), strlen("SYSTem:ERRor:ALL?"));

如果它可能修改数据,那么这将给出未定义的行为,并且您将需要该字符串的本地副本:

const char message[] = "SYSTem:ERRor:ALL?";
ibwrt(GpibDevice, message, strlen(message));

(您可以将长度指定为不太明显但可能更有效sizeof message - 1