C++常用方法笔记资料


目录

 

目录

​C++常用方法笔记资料​

​VS中常用的设置​

​C++函数注释规范:​

​使用fprintf保存数据​

​C++和OpenCV的Debug文件​

​获得路径中的文件名和文件前缀和后缀名​

​统计数组中每个元素出现的次数​

​数组与vector互转​

​openCV与vector互转​

​vector自定义排序方式​

​vector自定义查找元素​

​C++获取文件的时间等信息:#include ​

​JNI C++接口的笔记​

​size_t 和 size_type的区别​

​shared_ptr和make_shared​

​Cmake构建项目:​



VS中常用的设置

$(SolutionDir):表示当前解决方案的目录,如设置头文件路径可这样:$(SolutionDir)/extern/include;

$(ProjectDir):当前项目的目录路径

MFC应用程序显示控制台打印信息:生成事件->后期生成事件->命令行 中添加 :editbin /subsystem:console $(OutDir)\$(TargetName).exe,这样cout或者printf就可以向控制台输出信息了

C++常用方法笔记资料_#define


C++函数注释规范:

/********************************************************
* @brief : 函数实现功能
* @param para1: 参数说明
* @param para2: 参数说明
* @return : 返回内容
********************************************************/
int fun(int para1,float para2);

使用fprintf保存数据

int main() {
char name[20] = "lucy";
FILE *out;
out = fopen("output.txt", "w");
if (out != NULL)
fprintf(out, "%s\n", name);
return 0;
}

C++和OpenCV的Debug文件

Debug.h:

#ifndef DETECT_DEBUG_H
#define DETECT_DEBUG_H
#include "opencv2/opencv.hpp"
#include <chrono>

#define millisecond 1000000

using namespace std;
//debug info ON-OFF
#define __DEBUG__ON
#ifdef __DEBUG__ON
#define __DEBUG__WIN__ON //Window debug:print debug info
#define __DEBUG__IMSHOW__ON //show debug images
#define __DEBUG__IMWRITE__OFF //write debug images
#define __DEBUG__TIME__ON //run times test on/off
#define __DEBUG__ANDROID__OFF //android debug on/off

//#include <assert.h>
//#define DEBUG_ASSERT(...) assert( __VA_ARGS__)
//#define DEBUG_CV_ASSERT(...) CV_Assert( __VA_ARGS__)

#else
#define __DEBUG__ON(format,...)
#endif

//print debug info
#ifdef __DEBUG__WIN__ON
//#define DEBUG_PRINT(...) printf("File: %s, Line: %05d: "format"", __FILE__,__LINE__, ##__VA_ARGS__)
#define DEBUG_PRINT(...) printf( __VA_ARGS__);printf("\n")
#else
#define DEBUG_PRINT(format,...)
#endif



//show debug images
#ifdef __DEBUG__IMSHOW__ON
#define DEBUG_IMSHOW(...) showImages(__VA_ARGS__)
#else
#define DEBUG_IMSHOW(format,...)
#endif

//write debug images
#ifdef __DEBUG__IMWRITE__ON
#define DEBUG_IMWRITE(...) saveImage(__VA_ARGS__)
#else
#define DEBUG_IMWRITE(format,...)
#endif

//write debug images
#ifdef __DEBUG__ANDROID__ON
#include <android/log.h>
// Define the LOGI and others for print debug infomation like the log.i in java
#define LOG_TAG "SmartAlbum -- JNILOG"
//#undef LOG
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG, __VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG, __VA_ARGS__)
#else
#ifdef __DEBUG__WIN__ON
#define LOGI(...) printf( __VA_ARGS__); printf("\n")
#define LOGD(...) printf( __VA_ARGS__); printf("\n")
#define LOGW(...) printf( __VA_ARGS__); printf("\n")
#define LOGE(...) printf( __VA_ARGS__); printf("\n")
#define LOGF(...) printf( __VA_ARGS__); printf("\n")
#else
#define LOGI(...)
#define LOGD(...)
#define LOGW(...)
#define LOGE(...)
#define LOGF(...)
#endif
#endif

//run times test...
#ifdef __DEBUG__TIME__ON
#define LOG_TIME LOGE
#define RUN_TIME(time_) (double)(time_).count()/millisecond
//#define RUN_TIME(...) getTime_MS( __VA_ARGS__)

//设置计算运行时间的宏定义
#define DEBUG_TIME(time_) auto time_ =std::chrono::high_resolution_clock::now()
#define DEBUG_TIME_PRINT(time_) printf("run time: %s=%3.3f ms\n", #time_,(double)(time_).count()/millisecond)
#else
#define DEBUG_TIME(time_)
#endif

template<typename TYPE>
void PRINT_1D(string name,TYPE *p1, int len) {
printf("%s", name.c_str());
for (int i = 0; i < len; i++) {
printf("%f,", p1[i]);
}
cout << endl;
}


void showImages(const char *imageName, cv::Mat image);
void showImages(const char *imageName, cv::Mat img, cv::Rect face);
void showImages(const char *imageName, cv::Mat img, cv::Rect face, std::vector<cv::Point> pts);
void showImages(const char *imageName, cv::Mat img, std::vector<cv::Point> pts);




void saveImage(const char *imageName, cv::Mat image);
void saveImage(const char *imageName, cv::Mat image, std::vector<int> para);
void saveImage(const char *imageName, cv::Mat image, cv::Rect face, std::vector<cv::Point> pts);
void saveImage(const char *imageName, cv::Mat img, cv::Rect face);

vector<string> getFilesList(string dir);
void writeDatatxt(string path, string data, bool bCover=false);

#ifdef linux

#define _LINUX
#define separator "/"

#endif

#ifdef _WIN32//__WINDOWS_

#define _WINDOWS
#define separator "\\"
#endif


#endif

Debug.cpp:

#include "opencv2/opencv.hpp"
using namespace std;
#include "debug.h"


//*************************************显示图片****************************************
#define RESIZE(img_show,col) cv::resize(img_show, img_show, cv::Size(col, img_show.rows*col / img_show.cols))

void showImages(const char *imageName, cv::Mat img) {
cv::Mat img_show = img.clone();
if (img_show.channels() == 1)
cvtColor(img_show, img_show, cv::COLOR_GRAY2BGR);

//char str[200];
char str1[200];
strcpy(str1, imageName);
//sprintf(str, ",Size:%dx%d", image.rows, image.cols);
//strcat(str1, str);
RESIZE(img_show, 400);
cv::imshow(str1, img_show);
cv::waitKey(100);
}


void showImages(const char *imageName, cv::Mat img, cv::Rect face, std::vector<cv::Point> pts)
{
cv::Mat img_show = img.clone();
if (img_show.channels() == 1)
cvtColor(img_show, img_show, cv::COLOR_GRAY2BGR);

for (int i = 0; i < pts.size(); ++i) {
//std::cout << "index: " << i << std::endl;
cv::circle(img_show, pts.at(i), 2.f, cv::Scalar(0, 0, 255), -1, CV_AA);
// char str[3];
// itoa(i, str, 10);
// //line(imgDrawFace, cv::Point(shape.part(i).x(), shape.part(i).y()), cv::Point(shape.part(i).x(), shape.part(i).y()), cv::Scalar(0, i * 3, 255), 2);
// putText(img_show, str, pts.at(i), cv::FONT_HERSHEY_DUPLEX, 0.5, cv::Scalar(255, 0, 0));

}
cv::rectangle(img_show, face, { 255, 0, 0 }, 2);
char str[200];
char str1[200];
strcpy(str1, imageName);
//sprintf(str, ",Size:%dx%d", img.rows, img.cols);
//strcat(str1, str);
RESIZE(img_show, 400);
cv::imshow(str1, img_show);
cv::waitKey(100);
}


void showImages(const char *imageName, cv::Mat img, std::vector<cv::Point> pts)
{
cv::Mat img_show = img.clone();
if (img_show.channels() == 1)
cvtColor(img_show, img_show, cv::COLOR_GRAY2BGR);

for (int i = 0; i < pts.size(); ++i) {
//std::cout << "index: " << i << std::endl;
cv::circle(img_show, pts.at(i), 2.f, cv::Scalar(0, 0, 255), -1, CV_AA);
// char str[3];
// itoa(i, str, 10);
// //line(imgDrawFace, cv::Point(shape.part(i).x(), shape.part(i).y()), cv::Point(shape.part(i).x(), shape.part(i).y()), cv::Scalar(0, i * 3, 255), 2);
// putText(img_show, str, pts.at(i), cv::FONT_HERSHEY_DUPLEX, 0.5, cv::Scalar(255, 0, 0));
}
char str[200];
char str1[200];
strcpy(str1, imageName);
//sprintf(str, ",Size:%dx%d", img.rows, img.cols);
//strcat(str1, str);
RESIZE(img_show, 400);
cv::imshow(str1, img_show);
cv::waitKey(100);
}



void showImages(const char *imageName, cv::Mat img, cv::Rect face)
{
int thickness = img.cols*0.005;
thickness = thickness > 1 ? thickness : 1;
cv::Mat img_show = img.clone();
if (img_show.channels() == 1)
cvtColor(img_show, img_show, cv::COLOR_GRAY2BGR);

cv::rectangle(img_show, face, { 255, 0, 0 }, thickness);
char str[200];
char str1[200];
strcpy(str1, imageName);
//sprintf(str, ",Size:%dx%d", img.rows, img.cols);
//strcat(str1, str);
RESIZE(img_show, 400);
cv::imshow(str1, img_show);
cv::waitKey(100);
}

//*************************************保存图片****************************************


void saveImage(const char *imageName, cv::Mat image) {
cv::imwrite(imageName, image);
}

void saveImage(const char *imageName, cv::Mat image, std::vector<int> para) {
cv::imwrite(imageName, image, para);
}

void saveImage(const char *imageName, cv::Mat image, cv::Rect face, std::vector<cv::Point> pts) {
int thickness = image.cols*0.005;
thickness = thickness > 1 ? thickness : 1;
cv::Mat img = image.clone();
for (int i = 0; i < pts.size(); ++i) {
//std::cout << "index: " << i << std::endl;
cv::circle(img, pts.at(i), 2.f, cv::Scalar(0, 0, 255), thickness, CV_AA);
}
cv::rectangle(img, face, { 255, 0, 0 }, thickness);
cv::imwrite(imageName, img);
}

void saveImage(const char *imageName, cv::Mat img, cv::Rect face)
{
cv::Mat img_show = img.clone();
if (img_show.channels() == 1)
cvtColor(img_show, img_show, cv::COLOR_GRAY2BGR);
cv::rectangle(img_show, face, { 255, 0, 0 }, 2);
cv::imwrite(imageName, img_show);
}


//*************************************获取文件列表****************************************
#ifdef _LINUX
#include <memory.h>
#include <dirent.h>
vector<string> getFilesList(string dirpath) {
vector<string> allPath;
DIR *dir = opendir(dirpath.c_str());
if (dir == NULL)
{
cout << "opendir error" << endl;
return allPath;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL)
{
if (entry->d_type == DT_DIR) {//It's dir
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
string dirNew = dirpath + separator + entry->d_name;
vector<string> tempPath = getFilesList(dirNew);
allPath.insert(allPath.end(), tempPath.begin(), tempPath.end());

}
else {
//cout << "name = " << entry->d_name << ", len = " << entry->d_reclen << ", entry->d_type = " << (int)entry->d_type << endl;
string name = entry->d_name;
string imgdir = dirpath + separator + name;
//sprintf("%s",imgdir.c_str());
allPath.push_back(imgdir);
}

}
closedir(dir);
//system("pause");
return allPath;
}
#endif

#ifdef _WIN32//__WINDOWS_
#include <io.h>
vector<string> getFilesList(string dir)
{
vector<string> allPath;
// 在目录后面加上"\\*.*"进行第一次搜索
string dir2 = dir + separator+"*.*";

intptr_t handle;
_finddata_t findData;

handle = _findfirst(dir2.c_str(), &findData);
if (handle == -1) {// 检查是否成功
cout << "can not found the file ... " << endl;
return allPath;
}
while (_findnext(handle, &findData) == 0)
{
if (findData.attrib & _A_SUBDIR) 是否含有子目录
{
//若该子目录为"."或"..",则进行下一次循环,否则输出子目录名,并进入下一次搜索
if (strcmp(findData.name, ".") == 0 || strcmp(findData.name, "..") == 0)
continue;
// 在目录后面加上"\\"和搜索到的目录名进行下一次搜索
string dirNew = dir + separator + findData.name;
vector<string> tempPath = getFilesList(dirNew);
allPath.insert(allPath.end(), tempPath.begin(), tempPath.end());
}
else //不是子目录,即是文件,则输出文件名和文件的大小
{
string filePath = dir + separator + findData.name;
allPath.push_back(filePath);
}
}
_findclose(handle); // 关闭搜索句柄
return allPath;
}
#endif

//***********************************将数据保存到txt文本中*************************************
void writeDatatxt(string path, string data, bool bCover) {

//fstream fout(path, ios::app);
fstream fout;
if (bCover)
{
fout.open(path);//默认是:ios_base::in | ios_base::out
}
else
{
fout.open(path, ios::app);//所有写入附加在文件末尾
}
fout << data << endl;
fout.flush();
fout.close();
}

获得路径中的文件名和文件前缀和后缀名

#define separator  "\\"//分隔符
string image_path="D:\\dataset\\test.jpg"
string output_dir="D:\\out-dataset"
int index = image_path.find_last_of(separator);//获得最后一个“\\”的位置
string full_name = image_path.substr(index + 1);//获得文件名test.jpg
int prex_index = full_name.find_last_of('.');//获得最后一个“.”的位置
string prex_name = full_name.substr(0, prex_index);//获得文件名前缀test
string out_test_image = output_dir + separator + prex_name + "-lut.jpg";//结果为D:\\out-dataset\\test-lut.jpg

统计数组中每个元素出现的次数

 基本解决思路:
     首先我们声明一个大小和inputArray一样的数组countryArray,并将每个元素值初始化为-1,用来存储每个元素的频率。这需要一些技巧来达到和HashMap一样的效果却也不损失太多性能。
     if countArray[i] == -1,表示我们还没有统计inputArray[i]这个元素的频率; if countArray[i] == 0,表示我们已经统计过元素inputArray[i]的频率了。
     用循环遍历InputArray,from 0 到 N-1,统计每个元素的频率。

     对于当前元素inputArray[i],if countArray[i] == -1,我们就保存这个元素的频率到countArray[i];否则,不保存,因为之前已经统计过它了

#include <iostream>
using namespace std;

int main()
{
/*********************************************************************************/
int inputArray[12] = {9,1,2,1,3,1,2,2,3,4,9,9};
int countArray[12];
int elementCount = 12;
int i, j, count;
/* Read array elements */
for (i = 0; i < elementCount; i++) {
countArray[i] = -1;
}

/*
* for any element inputArray[i], If countArray[i] = -1,
* that means frequency is not counted for this number yet
* and countArray[i] = 0 means frequency is already
* counted for this number.
*/
for (i = 0; i < elementCount; i++) {
count = 1;
for (j = i + 1; j < elementCount; j++) {
if (inputArray[i] == inputArray[j]) {
countArray[j] = 0;//已经统计过置为0
count++;
}
}
if (countArray[i] != 0) {
countArray[i] = count;//记录首次出现的值在数组中出现的个数
}
}

/* Print count of each element */
for (i = 0; i<elementCount; i++) {
if (countArray[i] != 0) {
printf("Element %d : Count %d\n", inputArray[i], countArray[i]);
}
}
system("pause");
return 0;
}

   若使用vector类型,可以改为更加实用的例子:比如下面的函数可以实现统计vector中每个元素出现的次数,且出现次数不少于minCount的集合

#include <vector>
#include<algorithm>
#include <iostream>
using namespace std;
struct Grade
{
int value;//值
int count;//value值出现的次数
};

/** @brief 函数实现统计数组/vector中每个元素出现的次数,且出现次数不少于minCount
@param inputVector 输入vector类型的数据
@param minCount 出现不少于minCount次
@return 返回vector<Grade>类型
*/
vector<Grade> countElement(vector<int> inputVector,int minCount) {
//int *status =new int[inputVector.size()];
vector<int> status;//标记状态:0表示未统计,>1表示已经统计了
for (int i = 0; i < inputVector.size(); i++) {
//status[i] = -1;
status.push_back(0);
}
int v_size = inputVector.size();
int value1 = 0, value2 = 0;
int count = 0;//计数
vector<Grade> container;//保存结果
Grade perGrade;
for (size_t i = 0; i < v_size; i++) {
if (status[i] != 0)
continue;
count = 1;
value1 = inputVector.at(i);
status[i] = value1;
for (size_t j = i + 1; j < v_size; j++) {
if (status[j] != 0)
continue;
value2 = inputVector.at(j);
if (value1 == value2)
{
status[j] = value1;
count++;
}
}
if (count >= minCount)
{
perGrade.value = value1;
perGrade.count = count;
container.push_back(perGrade);
}
}
return container;
}

int main()
{
int inputArray[13] = {1,1,2,1,3,1,2,2,3,4,9,9,9};
vector<int> inputVector(inputArray, inputArray + sizeof(inputArray) / sizeof(int));
int minCount = 3;//统计vector中元素出现不少于minCount次数的元素
vector<Grade> container=countElement(inputVector,minCount);
system("pause");
return 0;
}

C++常用方法笔记资料_android_02

 


数组与vector互转

    利用vector的构造函数,可以很方便的将数组转为vector

int inputArray[12] = {9,1,2,1,3,1,2,2,3,4,9,9};
vector<int> inputVector(inputArray, inputArray + sizeof(inputArray) / sizeof(float));

由于vector内部的数据是存放在连续的存储空间,vector转数组事实上只需要获取vector中第一个数据的地址和数据的长度即可。如果仅仅是传参,无需任何操作,直接传地址即可,如果要进行数据复制,可以借用内存拷贝函数“memcpy”。例如:

int *buffer = new int[inputVector.size()];
if (!inputVector.empty())
{
memcpy(buffer, &inputVector[0], inputVector.size() * sizeof(int));
}

     下面的例子可实现vector中按照age的大小排序

#include <vector>
#include<algorithm>
#include <iostream>
using namespace std;

struct dataInfo
{
string name;
int age;
};

//降序
bool descendingOrder(const dataInfo &a, const dataInfo &b)
{
return a.age > b.age;
}
//升序
bool ascendingOrder(const dataInfo &a, const dataInfo &b)
{
return a.age < b.age;
}

int main()
{
vector<dataInfo> v;
dataInfo data;
data.age = 10;
data.name = "A";
v.push_back(data);
data.age = 40;
data.name = "B";
v.push_back(data);
data.age = 20;
data.name = "C";
v.push_back(data);
data.age = 30;
data.name = "D";
v.push_back(data);
sort(v.begin(), v.end(), descendingOrder);
system("pause");
return 0;
}

vector自定义查找元素

    下面的方法可以实现vector查找指定元素是否存在

#include <vector>  
#include<algorithm>
#include <iostream>
#include <string>
using namespace std;

struct dataInfo
{
string name;
int age;
//dataInfo(string _name, int _age) : name(_name), age(_age) {}
};
bool operator == (const dataInfo& a, const dataInfo& b) {
return a.age == b.age;

}

int main()
{
vector<dataInfo> v;
dataInfo data;
data.age = 10;
data.name = "A";
v.push_back(data);
data.age = 40;
data.name = "B";
v.push_back(data);
data.age = 20;
data.name = "C";
v.push_back(data);
data.age = 30;
data.name = "D";
v.push_back(data);
data.age = 20;
data.name = "E";
v.push_back(data);
//
dataInfo t;
t.age = 20;//查找年龄为20
vector<dataInfo>::iterator ifind = find(v.begin(), v.end(), t);
if (ifind != v.end())
{
cout << "index=" << ifind- v.begin()<< endl;
cout << "data:name="<< ifind->name <<",age="<< ifind->age<<endl;
}

system("pause");
return 0;
}

     一种更通用的方法是:下面的程序实现:

    【1】判断vector的某一元素是否存在,并返回下标

    【2】查找vector中最大,最小值的元素,并返回下标

#include <vector>  
#include<algorithm>
#include <iostream>
#include <string>

using namespace std;
struct dataInfo
{
string name;
int age;
//dataInfo(string _name, int _age) : name(_name), age(_age) {}
};

/*******判断vector的某一元素是否存在,并返回下标 **********/
bool operator == (const dataInfo& a, const dataInfo& b) {
return a.age == b.age;
}
template<typename _Tp>
int find_element_in_vector(const vector<_Tp> v, const _Tp element) {
vector<_Tp>::const_iterator it = find(v.begin(), v.end(), element);
if (it != v.end()) {
return it - v.begin();
}
else {
return -1;
}
}

/*******查找vector中最大,最小值的元素,并返回下标 **********/
bool cmp(const dataInfo& a, const dataInfo& b)
{
return a.age< b.age;
}

void main() {

vector<dataInfo> v;
dataInfo data;
data.age = 10;
data.name = "A";
v.push_back(data);
data.age = 40;
data.name = "B";
v.push_back(data);
data.age = 30;
data.name = "C";
v.push_back(data);
data.age = 30;
data.name = "D";
v.push_back(data);
data.age = 20;
data.name = "E";
v.push_back(data);
/**************************查找指定元素的位置*************************/
dataInfo t;
t.age = 20;//查找年龄为20
int index = find_element_in_vector(v, t);

/**************************查找最大值*************************/
dataInfo maxValue;
///std::vector<int>::iterator maxIte = max_element(v.begin(), v.end());//若是基本数据类型
std::vector<dataInfo>::iterator maxIte = max_element(v.begin(), v.end(),cmp);//结构体类型
if (maxIte != v.end())
{
index = maxIte - v.begin();
maxValue = *maxIte;
}

/**************************查找最小值*************************/
dataInfo minValue;
///std::vector<int>::iterator minIte = min_element(v.begin(), v.end());//若是基本数据类型
std::vector<dataInfo>::iterator minIte = min_element(v.begin(), v.end(), cmp);//结构体类型
if (minIte != v.end())
{
index = minIte - v.begin();
minValue = *minIte;
}

}

C++获取文件的时间等信息:#include <sys/stat.h>

string filePath = "D:\\SmartAlbum\\image1\\i.jpg";
struct stat buf;
struct tm* tim;
int result = stat(filePath.c_str(), &buf);
//显示文件状态信息
if (result != 0)
perror("显示文件状态信息出错");
else
{
cout << "文件创建时间:" << ctime(&buf.st_ctime);
cout << "访问日期:" << ctime(&buf.st_atime);//注意这里访问时间为00:00:00为正常
cout << "最后修改日期:" << ctime(&buf.st_mtime);
cout << "时间值:" << buf.st_ctime << endl;
tim = localtime(&buf.st_ctime);
printf("创建时间%d:%d:%d:%d:%d:%d\n",
tim->tm_year,
tim->tm_mon,
tim->tm_yday,
tim->tm_hour,
tim->tm_min,
tim->tm_sec);
}

JNI C++接口的笔记

Java接口定义:

public static native void transferImage_yuv420_888( byte[] Camera_y, int rowStride_y,     int pixStride_y,
byte[] Camera_u, int rowStride_u, int pixStride_u,
byte[] Camera_v, int rowStride_v, int pixStride_v,
int width, int height);

JNI对应的的C++接口:接口简单实现Y数组加100,由于是通过指针直接对原数组进行操作,因此不需要返回结果

}extern "C"
JNIEXPORT void JNICALL
Java_com_example_lenovo_transfer_Transfer_transferImage_1yuv420_1888(JNIEnv *env, jclass type,
jbyteArray Camera_y_, jint rowStride_y, jint pixStride_y,
jbyteArray Camera_u_, jint rowStride_u, jint pixStride_u,
jbyteArray Camera_v_, jint rowStride_v, jint pixStride_v,
jint width, jint height) {
jbyte *Camera_y = env->GetByteArrayElements(Camera_y_, NULL);
jbyte *Camera_u = env->GetByteArrayElements(Camera_u_, NULL);
jbyte *Camera_v = env->GetByteArrayElements(Camera_v_, NULL);
// TODO
unsigned char *y = (unsigned char *) Camera_y;
unsigned char *u = (unsigned char *) Camera_u;
unsigned char *v = (unsigned char *) Camera_v;
for (size_t i=0; i < height; i++){
for (size_t j=0; j < width; j++) {
*y=*y+100;
y++;
}
}
env->ReleaseByteArrayElements(Camera_y_, Camera_y, 0);
env->ReleaseByteArrayElements(Camera_u_, Camera_u, 0);
env->ReleaseByteArrayElements(Camera_v_, Camera_v, 0);
}

size_t 和 size_type的区别

 为了使自己的程序有很好的移植性,c++程序员应该尽量使用size_t和size_type而不是int, unsigned

  • size_t是全局定义的类型;size_type是STL类中定义的类型属性,用以保存任意string和vector类对象的长度
  • string::size_type 制类型一般就是unsigned int, 但是不同机器环境长度可能不同 win32 和win64上长度差别;size_type一般也是unsigned int
  • 使用的时候可以参考:
string::size_type  a =123;
vector<int>size_type b=234;
size_t b=456;

 

  • size_t 使用的时候头文件需要 <cstddef> ;size_type 使用的时候需要<string>或者<vector>
sizeof(string::size_type) 
sizeof(vector<bool>::size_type)
sizeof(vector<char>::size_type)
sizeof(size_t)

     上述长度均相等,长度为win32:4 win64:8

  • 二者联系:在用下标访问元素时,vector使用vector::size_type作为下标类型,而数组下标的正确类型则是size_t

shared_ptr和make_shared

std::shared_ptr<TNN_NS::TNN> net = std::make_shared<TNN_NS::TNN>();

Cmake构建项目:

项目结构:​​https://github.com/PanJinquan/opencv-learning-tutorials/tree/master/cmakeDemo​

C++常用方法笔记资料_android_03

根目录CmakeLists.txt:

cmake_minimum_required(VERSION 3.5)
# 参考资料:
# http://www.hahack.com/codes/cmake/


project(cmakeDemo)

# 指定头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)

# 指定可执行文件的输出目录,输出到bin下面
#set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

#指定库文件输出路径
#set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

# 将myhello子工程加入到主工程,里面必须含有CMakeLists.txt文件
add_subdirectory(myhello)

#指定可执行文件的输出目录,输出到bin下面
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

#指定库文件输出路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)


set(LIB_MY my_lib)

# 在指定目录下查找库,并保存在LIBPATH变量中:
# find_library (<VAR> name1 [path1 path2 ...])
# find_library(LIB_MY my_lib ${PROJECT_SOURCE_DIR}/lib)


# 构成可执行文件
add_executable(Demo main.cpp)

# 链接的库文件
# link_libraries( ${LIB_MY})

# 添加链接库:将子模myhello链接到Demo中
#target_link_libraries (Demo ${LIB_MY_LIB})
target_link_libraries (Demo ${LIB_MY})

myhello目录的CMakeLists.txt文件

cmake_minimum_required(VERSION 3.5)
# 常用的变量:
# . 表示当前目录
# ${PROJECT_SOURCE_DIR}:工程的根目录

# 指定头文件目录,PROJECT_SOURCE_DIR为工程的根目录
include_directories(${PROJECT_SOURCE_DIR}/include)



#指定可执行文件的输出目录,输出到bin下面
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

#指定库文件输出路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)


# 将指定的源文件生成链接文件myhello
# add_library(myhello myhello.cpp)
# 更加便捷的方法是使用aux_source_directory(<dir> <variable>)
# 查找当前目录下的所有源文件,并将名称保存到 DIR_SRCS 变量中
aux_source_directory(${PROJECT_SOURCE_DIR}/myhello DIR_SRCS)

add_library(my_lib ${DIR_SRCS})
#set_target_properties(my_lib PROPERTIES OUTPUT_NAME "my_lib")