zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C++常用方法笔记资料

C++方法笔记 常用 资料
2023-09-11 14:17:47 时间

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++函数注释规范:

/********************************************************
*	@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;
}

 


数组与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));
	}

 参考资料:https://blog.csdn.net/Sagittarius_Warrior/article/details/54089242

openCV与vector互转

  请参考:https://blog.csdn.net/guyuealian/article/details/80253066

vector自定义排序方式

     下面的例子可实现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

根目录CmakeLists.txt:

cmake_minimum_required(VERSION 3.5)
# 参考资料:
# http://www.hahack.com/codes/cmake/
# https://blog.csdn.net/weicao1990/article/details/72844995

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")