今天在Qt(C++图形库)中使用extern "C"的办法使用C方法的时候遇到一个奇怪的问题。同一个字符串,在C方法内部测出的长度和在Qt中测出的长度不相等。并且如果在C方法内部没有写printf,则会导致字符串参数传递错误。如下:
首先,不在C方法内部使用printf.
本代码一共3个文件MyClass.h,MyClass.cpp,Main.cpp,如下:
/******MyClass.h******/
#ifndef MYCLASS_H_
#define MYCLASS_H_
class MyClass
{
public:
MyClass();
char * getString();
void showInfo();
};
#endif
/********MyClass.cpp**********/
#include "MyClass.h"
#include <stdio.h>
#include <string.h>
extern "C"{
#include<stdio.h>
#include<string.h>
char * MyClass::getString(){
char buf[]="4-T1-3-AAAAAAA,BBBBBBB,CCCCCCC,DDDDDDD,EEEEEEE\0";
return buf;
}
}
MyClass::MyClass()
{
showInfo();
}
void MyClass::showInfo()
{
char *cc=getString();
int ii=strlen(cc);
printf("ii=%d\n",ii);
}
/*********Main.cpp**********/
#include <QApplication> //所有QT应用程序都要包含QApplication头文件
#include "MyClass.h"
#include <QtCore/QTextCodec>
int main(int argc,char * argv[])
{
QApplication app(argc,argv);
MyClass clazz;
return app.exec();
}
运行后截图如下:
然后在C方法内部加上printf,其它代码不作任何改变,如下:
/***********MyClass.cpp**************/
#include "MyClass.h"
#include <stdio.h>
#include <string.h>
extern "C"{
#include<stdio.h>
#include<string.h>
char * MyClass::getString(){
char buf[]="4-T1-3-AAAAAAA,BBBBBBB,CCCCCCC,DDDDDDD,EEEEEEE\0";
int mm=strlen(buf);
printf("mm=%d\n",mm); // 就是这儿增加一个printf
return buf;
}
}
MyClass::MyClass()
{
showInfo();
}
void MyClass::showInfo()
{
char *cc=getString();
int ii=strlen(cc);
printf("ii=%d\n",ii);
}
然后,运行结果如下:
通过如上的代码和运行截图,我们可以看到
(1)在使用printf前和使用printf后,获得的字符串的长度不一样,一个是24一个是28。
(2)相同的字符串,在C方法内部获得的长度和在C++(Qt)中获取的长度不一样,一个是46,一个是28.
都怪我是菜鸟,今天请教了高人,原来是char *cc=getString()这儿错了,因为我在getString()函数中定义的字符数组是一个局部变量,而局部变量在函数调用完毕后会被销毁,如果仍然使用指针指向这个变量那么就会产生不可预知的错误。所以找到的一个方法就是将char buf[]设为全局的,也就是拿到函数体外边去定义,并且返回的时候也返回这个全局变量的指针。经本人测试,这样做后完全正确了。
注:听高手说,这是菜鸟常犯的错误之一。千万注意,有的地方不能将局部变量直接返回。
(------完------)