C++跨平臺編譯的一些總結
阿新 • • 發佈:2019-01-02
最近一段時間將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;