最近一段时间将windows的C++程序迁到linux下编译,python调用so,感觉有不少坑花费的时间也比较长,记录如下:
1. string 和 char* 的问题:
在windows上运行良好的程序中有一个函数返回值类型为string,而放到Linux上运行时进入函数之后报段错误无返回值没响应,(后来发现应该是linux对C支持,而string属于C++)纠结半天将其换成char*类型,返回值强转 return const_cast<char*>(strname.c_str()); 运行成功。之后又写了循环,循环调用此函数后发现,本来输入视频输出hash码存入mysql时,在运行几个之后随机的缺失了一些返回值,在return之前是可以输出的,但是调用的返回没有值。就这样mysql里面有一小部分没有值。
找了一天没发现原因,而在windows上返回char*时,输出时乱码,之后还是my boyfriend中间换了一下返回值类型如下成功了,在linux和windows上均可以了:
char* get_hash(){
string myhash;
int length = myhash.length();
char* tempHash;
tempHash = new char[length];
strpy(tempHash, myhash.c_str());
return tempHash;
}
2.还是上一个函数,程序中两次调用,第一次返回正常,第二次累加第一次的结果:
在定义string myhash; 时将后面加一个 myhash.clear(); 清理之前的结果。
string myhash;
myhash.clear();
3.windows遍历目录下的文件:
Directory dir;
vector<string> filenames = dir.GetListFiles(imgpath1,"*",false);
for(int i=0;i<filenames.size();i++){
char szPath[255] = {0};
sprintf_s(szPath,"%s\\%s",imgpath1,filenames[j].c_str());
cout<<szPatch<<endl;
}
或者第二种方法,其输入格式(“path\\*.*”):
void listFiles(const char * dir, vector<string>& imageNames) //window下搜索目录 输入路径格式“trsin\\*.*”缺点不好拼接
{
intptr_t handle;
_finddata_t findData;
handle = _findfirst(dir, &findData); // 查找目录中的第一个文件
if (handle == -1)
{
cout << "Failed to find first file!\n";
return;
}
do
{
if (findData.attrib & _A_SUBDIR
&& strcmp(findData.name, ".") == 0
&& strcmp(findData.name, "..") == 0
) { // 是否是子目录并且不为"."或".."
cout << findData.name << "\t<dir>\n";
}
else {
if (findData.size == 0) {
continue;
}
else {
imageNames.push_back(findData.name);
}
}
} while (_findnext(handle, &findData) == 0); // 查找目录中的下一个文件
cout << "Done!\n";
_findclose(handle); // 关闭搜索句柄
}
4.linux下搜索路径下文件:
void listFiles(const char * dir)
{
DIR *dp;
struct dirent *entry;
if ((dp = opendir(dir)) == NULL)
{
cout << "cannot open::" << dir << endl;
}
while ((entry = readdir(dp)) != NULL)
{
if (strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0)
{
continue;
}
cout << entry->d_name << endl;
}
}
5.python调用so包,指针问题:
videohash = so.getHash
videohash.restype = ctypes.c_char_p
src1 = videohash("videoName",3)
print(src1)
6.linux没有BMP类:
Linux没有BMP头文件类自己定义,并包含进去头文件:
#include <iostream>
typedef struct tagBITMAPFILEHEADER{
unsigned short bfType; //2 此处需留意
unsigned long bfSize; //4 /* File size in bytes */
unsigned short bfReserved1; //2
unsigned short bfReserved2; //2
unsigned long bfOffBits; //4 /* Offset to image data, bytes */
} __attribute__((packed))BITMAPFILEHEADER, *PBITMAPFILEHEADER; //Attention:"__"是两个"_"! 字边界对齐!4字节对齐 知道在linux的gcc下默认的是四字节的
typedef struct tagBITMAPINFOHEADER{
unsigned long biSize; //4 /* Header size in bytes */
long biWidth; //4 /* Width of image */
long biHeight; //4 /* Height of image */
unsigned short biPlanes; //2 /* Number of colour planes */
unsigned short biBitCount; //2 /* Bits per pixel */
unsigned long biCompression; //4 /* Compression type */
unsigned long biSizeImage; //4 /* Image size in bytes */
long biXPelsPerMeter; //4
long biYPelsPerMeter; //4 /* Pixels per meter */
unsigned long biClrUsed; //4 /* Number of colours */
unsigned long biClrImportant; //4 /* Important colours */
} __attribute__((packed))BITMAPINFOHEADER,*PBITMAPINFOHEADER;
typedef struct tagRGBQUAD {
unsigned char rgbBlue; /* Blue value */
unsigned char rgbGreen; /* Green value */
unsigned char rgbRed; /* Red value */
unsigned char rgbReserved; /* Reserved */
} RGBQUAD;