cpp常用功能
编译器检测CPU框架
1 2 3 4 5
| #if defined(__x86__) || defined(__x86_64__) std::cout << "x86 arch used" << std::endl; #elif defined(__arm__) || defined(__aarch64__) std::cout << "arm arch used" << std::endl; #endif
|
lambda处理vector求和
1 2 3 4
| std::vector<int> numbers { 1, 2, 3, 4, 5, 10, 15, 20, 25, 35, 45, 50 }; int sum = 0; std::for_each(numbers.begin(), numbers.end(), [&sum] (const int& i) { sum += i;}); cout<<sum<<endl;
|
计算机支持的并发线程数
std::thread标准库中提供了hardware_concurrency()函数,该函数返回当前计算机支持的并发线程数,通常是cpu核数,如果值无法计算则返回0。
1
| auto num = std::thread::hardware_concurrency();
|
std::future
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void A::test(const int val) { usleep(val * 1000); }
void A::testAsync(const int val) { static std::future<void> wAsync; if (wAsync.valid() && wAsync.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout) { return; } wAsync = std::async(std::launch::async, &SmBuzzer::test, this, val); }
|
字符串split
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| std::vector<std::string> split(const std::string &strtem, const char a) { std::vector<std::string> strvec;
std::string::size_type pos1, pos2; pos2 = strtem.find(a); pos1 = 0; while (std::string::npos != pos2) { strvec.push_back(strtem.substr(pos1, pos2 - pos1)); pos1 = pos2 + 1; pos2 = strtem.find(a, pos1); } strvec.push_back(strtem.substr(pos1)); return strvec; }
|
数组转换成固定长度的字符串
1 2 3
| char ss[10]; int i = 6; sprintf(ss, "%04d", i);
|
数字转固定长度字符串
1 2 3
| int n_zero = 4; string number = "2"; std::string str = std::string(n_zero - number.length(), '0') + number;
|
std::vector释放
std::vector的clear和earse并不会释放对应的空间,只有在退出变量的生命周期时会释放,可使用如下方式释放:
1 2 3 4
| { std::vecotr<T> empty; a.swap(empty) }
|
数值最大值
1 2 3 4 5
| #include <iostream>
int max1 = std::numeric_limits<int32_t>::max(); int max2 = INT_MAX;
|
std::unorder_map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <unorder_map>
struct PairHash { template <class T1, class T2> std::size_t operator()(const std::pair<T1, T2> &p) const { auto h1 = std::hash<T1>{}(p.first); auto h2 = std::hash<T2>{}(p.second);
return h1 ^ h2; } };
std::unordered_map<std::pair<std::string, uint64_t>, std::unordered_map<std::string, std::vector<Type>>, PairHash> kv;
|
linux64虚拟地址转换物理地址
来源:https://blog.51cto.com/u_15315240/5108864
cat /proc/[pid]/maps
查看进程的虚拟内存地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <fcntl.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h>
size_t virtual_to_physical(pid_t pid, size_t addr) { char str[20]; sprintf(str, "/proc/%u/pagemap", pid); int fd = open(str, O_RDONLY); if(fd < 0) { printf("open %s failed!\n", str); return 0; } size_t pagesize = getpagesize(); size_t offset = (addr / pagesize) * sizeof(uint64_t); if(lseek(fd, offset, SEEK_SET) < 0) { printf("lseek() failed!\n"); close(fd); return 0; } uint64_t info; if(read(fd, &info, sizeof(uint64_t)) != sizeof(uint64_t)) { printf("read() failed!\n"); close(fd); return 0; } if((info & (((uint64_t)1) << 63)) == 0) { printf("page is not present!\n"); close(fd); return 0; } size_t frame = info & ((((uint64_t)1) << 55) - 1); size_t phy = frame * pagesize + addr % pagesize; close(fd); printf("The phy frame is 0x%zx\n", frame); printf("The phy addr is 0x%zx\n", phy); return phy; }
int main(void) { while(1) { uint32_t pid; uint64_t virtual_addr; printf("Please input the pid in dec:"); scanf("%u", &pid); printf("Please input the virtual address in hex:"); scanf("%zx", &virtual_addr); printf("pid = %u and virtual addr = 0x%zx\n", pid, virtual_addr); virtual_to_physical(pid, virtual_addr); } return 0; }
|
linux signal
1 2 3 4 5 6 7 8 9
| static void SigHandle(int sig) { std::this_thread::sleep_for(std::chrono::seconds(3)); exit(0); }
void main() { signal(SIGINT, SigHandle); }
|
windows读取共享内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| std::string readDataFromMem(const std::string &key) { HANDLE file = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, key.data()); if (!file) { return std::string(); } LPVOID lpBase = MapViewOfFile(file, FILE_MAP_ALL_ACCESS, 0, 0, 0);
char buffer[INT_MAX / 2] = {0}; strcpy_s(buffer, (char *)lpBase);
UnmapViewOfFile(lpBase); CloseHandle(file);
std::string data(buffer); return std::move(data); }
|
读取共享内存,转图像数据。数据为encode后的图像格式数据,以字符串读取,再decode:
1 2 3 4 5 6 7 8 9 10
| cv::Mat readFromMem(std::string key) { auto data = readDataFromMem(key); if (data.empty()) { return cv::Mat(); } cv::Mat img = cv::Mat(1, (int)data.size(), CV_8U, (char *)data.data()); return cv::imdecode(img, cv::IMREAD_UNCHANGED); }
|
如果内存中存的是cv::Mat().data图像数据,则使用以下转换:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| bool readMatFromMem(const std::string &key, int64_t size, cv::Mat &dst) { if (dst.empty()) { return false; } HANDLE file = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, key.data()); if (!file) { return false; } LPVOID lpBase = MapViewOfFile(file, FILE_MAP_ALL_ACCESS, 0, 0, 0);
memcpy(dst.data, (void *)lpBase, size); UnmapViewOfFile(lpBase); CloseHandle(file); return true; }
auto image = cv::Mat::zeros(rows, cols, type); readMatFromMem(key, size, image);
|
windows控制台程序鼠标事件不阻塞程序运行。。
windows控制台程序,双击运行后,防止鼠标时间阻塞程序运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| void disableMouseInCmd() { HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); DWORD dwInputMode = 0; GetConsoleMode(hInput, &dwInputMode); dwInputMode &= ~ENABLE_QUICK_EDIT_MODE; dwInputMode &= ~ENABLE_MOUSE_INPUT; dwInputMode &= ~ENABLE_WINDOW_INPUT; dwInputMode |= ENABLE_PROCESSED_INPUT; SetConsoleMode(hInput, dwInputMode); }
|