c/c++/c++11
文章平均质量分 63
10km
这个作者很懒,什么都没留下…
展开
-
c/c++:CMakeLists.txt中添加编译/连接选项使用内存错误检测工具Address Sanitizer(ASan)
Address Sanitizer(ASan)是一个快速的内存错误检测工具。从gcc 4.8开始,AddressSanitizer成为gcc的一部分。既然是gcc内置的内存检查工具,用起来比第三方的库更方便些。上述示例中:代码的含义是使用cmake generator-expression(生成器表达式)指定只在编译器为gcc,且操作系统为Linux时增加编译选项同理,也是在编译器为gcc,且操作系统为Linux时增加链接选项。原创 2024-09-02 13:07:12 · 783 阅读 · 0 评论 -
c++模板:调用模板成员函数需不需要加template关键字?
以下是个简单的模板类测试代码,模板类A中定义了模板函数hello,在模板函数test中调用A::hellotemplate_test.cpptemplate <class T>struct A{ template<class I> void hello(){} template<class I> void hello2(I i){}};template <class T>void test(A<T> & a){ a.原创 2022-03-18 13:31:20 · 2048 阅读 · 1 评论 -
C++11:读取properties文件的第三方库cpp_properties
在Java开发环境中JDK内置了java.util.Properties类用于读取.properties文件,在Java应用开发时广泛用于读取参数配置文件。最近在C++环境下做一个项目设计,也希望能通过读取.properties文件来获取参数配置文件.在github上找到了这个C++11实现的读取.properties文件的项目github.com/glywk/cpp_properties 。完全支持Java properteis语法。cpp_properties使用起来很简单,全部源码都是用C++11原创 2022-01-27 15:19:16 · 1707 阅读 · 0 评论 -
C/C++:std::thread构造函数死锁问题:WIN32下不可以在DllMain中创建线程
最近在设计一个动态库时,在全局变量中创建了线程,在Windows下动态库加载时导致死锁。根本的原因是Windows要求不可以在动态库的DllMain函数中创建线程,而我的代码结构恰好满足这个条件。以下是简化后的示例代码:class_a.hpp#include <thread> // c++11 support#include <iostream>class A { A(){ // 启动线程 std::thread t([]{ std::cout <<原创 2022-01-07 13:23:56 · 1120 阅读 · 1 评论 -
c++11:nlohmann::json进阶使用(三)使用basic_json模板类
nlohmann::json是非常好用的一个json开源解析库.nlohmann/json的源码是基于C++11标准写的,整个源码就是一个文件 nlohmann/json.hpp,引用非常方便。关于nlohmann/json的基本使用官网(https://github.com/nlohmann/json)上有比较详细的介绍。这里不再赘述,本文主要是介绍在nlohmann/json的基本使用之外一些我在使用 nlohmann/json 用到的一些扩展功能和重要但不太被了解的特性。我的上一篇博客里解决了第三原创 2021-11-26 14:52:29 · 3112 阅读 · 0 评论 -
c++11:nlohmann::json进阶使用(二)应用adl_serializer解决第三方数据类型(such as uri)的序列化和反序列化
nlohmann::json是非常好用的一个json开源解析库.nlohmann/json的源码是基于C++11标准写的,整个源码就是一个文件 nlohmann/json.hpp,引用非常方便。关于nlohmann/json的基本使用官网(https://github.com/nlohmann/json)上有比较详细的介绍。这里不再赘述,本文主要是介绍在nlohmann/json的基本使用之外一些我在使用 nlohmann/json 用到的一些扩展功能和重要但不太被了解的特性。uriben-zen/u原创 2021-11-26 13:11:40 · 2635 阅读 · 0 评论 -
c++11:nlohmann::json进阶使用(一)ordered_json
nlohmann::json是非常好用的一个json开源解析库.nlohmann/json的源码是基于C++11标准写的,整个源码就是一个文件 nlohmann/json.hpp,引用非常方便。关于nlohmann/json的基本使用官网(https://github.com/nlohmann/json)上有比较详细的介绍。这里不再赘述,本文主要是介绍在nlohmann/json的基本使用之外一些我在使用 nlohmann/json 用到的一些扩展功能和重要但不太被了解的特性。ordered_json原创 2021-11-26 11:57:09 · 4812 阅读 · 2 评论 -
C:基于可以自动扩展缓冲区的stringbuffer,实现内存格式化输出(bufprintf)
最近做一个C语言的嵌入式项目,需要分段向指定内存调用vsnprintf输出不定长度的格式化输出,因为是分段输出,而且长度不定,所以一开始就不能分配固定长度内存,每次输出都要从输出到上次的结尾开始,所以还要记录每次的输出长度。还是Java开发方便,有现成的StringBuffer可以用,不停的向StringBuffer调用 append添加就好了,哪有这么麻烦。为了解决这个麻烦,我参照Java中的StringBuffer对象,实现了一个 stringbuffer,并基于它实现bufprintf函数可以向st原创 2021-11-19 14:24:06 · 1179 阅读 · 0 评论 -
C:_debug_printf,基于vsnprintf 或 vprintf实现带时间戳和源码信息(__FILE__,__FUNCTION__, __LINE__)的格式化打印输出
写C程序的时候,printf输出调试信息是常态,printf输出调试信息时如果能自动带源码信息(__FILE__,__FUNCTION__, __LINE__),显然更方便查找问题,如果能再加上时间戳就更完美了。如果到处都用printf("%s:%s:%d, %s\n",__FILE__,__FUNCTION__, __LINE__,"hello")写起来也太麻烦了;而且有的时候还需要向内存缓冲区打印输出。而且__FILE__提供的是源码的全路径名,打印实可能会很长。所以这种直接在代码写printf("原创 2021-11-16 15:43:43 · 1835 阅读 · 0 评论 -
C:基于GNU regex(regex.h)regexec实现正则表达式多次匹配
GNU regex是GNU提供的跨平台的POSIX 正则表达式库(C语言)。不算GNU提供的扩展函数,POSIX标准的regex库总共就4个函数regcomp,regerror,regexec,regfree.我们知道 regexec 不能通过一次调用找到字符串中所有满足匹配条件的字符串位置,所以需要通过步进偏移的方式循环执行regexec才能把字符串中所有满足条件的匹配找出来, 每一次匹配的起始偏移是上一次匹配到的字符串结束偏移。在上一篇博客《C: GNU regex library (regex.原创 2021-11-15 16:44:39 · 2255 阅读 · 0 评论 -
C: GNU regex library (regex.h)正则表达式调用示例
GNU regex是GNU提供的跨平台的POSIX 正则表达式库(C语言)。我也是最近才接触这个相对于C++/Java实现来说非常简陋,勉强够用的正则表达式库。不算GNU提供的扩展函数,POSIX标准的regex库总共就4个函数regcomp,regerror,regexec,regfree,以下以完整源码的方式调用以上函数完成对GNU regex library的基本测试。gnuregex_test.c详细解释参见源码中的注释/*********************************原创 2021-11-14 17:03:40 · 3857 阅读 · 4 评论 -
cmake:MSVC,GNU解决bigobj问题
当代码中使用了大量模板时,会导致编译出的OBJ文件巨大,编译器会报错,在MSVC下错误为 Fatal Error C1128在GNU C++下错误提示为 too many sections…File too big解决办法也不复杂:在MSVC下要添加编译选项 /bigobj在GNU C++下要添加编译选项 -Wa,-mbig-obj在cmake脚本中,可以使用cmake-generator-expressions以如下的简洁方式设置MSVC和GNU的编译选项:add_executable(it原创 2021-11-12 15:48:02 · 5887 阅读 · 0 评论 -
cmake:VS2015和GCC编译paho.mqtt C/C++ client
paho.mqtt.c是eclipse开发的C语言跨平台mqtt client 开源库,paho.mqtt.cpp是对应的C++ Client,paho.mqtt支持CMAKE编译,本文以脚本形式提供了使用CMAKE基于VS2015/Windows以及GCC/MinGW的编译过程。环境要求cmake 这是必须的编译工具Visual Studio 2015 OR MinGW for windowsgcc for linuxVisual Studio 2015 编译脚本msvc_build.bat原创 2021-11-10 11:41:42 · 1536 阅读 · 0 评论 -
cmake:VS2015和GCC编译cpp_redis
cpp_redis是一个基于C++11编写的支持跨平台的redis客户端。使用起来很方便,cpp_redis支持CMAKE编译,编译也很简单,本文以脚本形式提供了使用CMAKE基于VS2015/Windows以及GCC/MinGW的编译过程。环境要求cmake 这是必须的编译工具Visual Studio 2015 OR MinGW for windowsgcc for linuxVisual Studio 2015 编译脚本msvc_build.bat要求cpp_redis源码文件夹与ms原创 2021-11-09 17:10:26 · 1058 阅读 · 0 评论 -
cmake:VS2015和GCC编译cJSON
cJSON是基于ANSI C的跨平台JSON解析开源库,在嵌入式应用中使用比较广泛, cJSON支持CMAKE编译,本文以脚本形式提供了使用CMAKE基于VS2015/Windows以及GCC/MinGW的编译过程。环境要求cmake 这是必须的编译工具Visual Studio 2015 OR MinGW for windowsgcc for linuxVisual Studio 2015 编译脚本msvc_build.bat要求cJSON源码文件夹与msvc_build.bat脚本在同一原创 2021-11-09 11:01:47 · 716 阅读 · 0 评论 -
C语言:跨平台环境下使用snprintf,vsnprintf系列函数要注意返回值的问题
标准C语言函数snprintf,vsnprintf系列函数可以向指定的缓冲区输出格式化打印的字符串。如果指定的缓存区足够大,那么调用正常,返回值就是写入缓存区的字节长度(不含结尾'\0')那么缓存区不够大的情况呢?本文要说的是这系列函数的在缓存区长度不足以输出所有内容时的返回值在不同一编译器提供的实现表现是不同的。我们用如下一段简单的测试代码来验证其返回值表现。#include <stdio.h>#include <errno.h>#include <string原创 2021-11-08 17:24:27 · 2106 阅读 · 0 评论 -
MSVC下使用gnu regex(正则表达式C语言接口regex.h)
最近我的一个跨平台项目遇到了一个问题:需要在MSVC下调用linux下才有正则表达式C接口(regex.h)。我们知道linux上提供了C接口的正则表达式调用(regex.h),但是在windows下MSVC并没有同样的regex.h.linux上的regex实现实际上是GNU提供的。如果找到对应的源码并且在win32下可编译,就可以解决问题。循着这个思路我在这里(https://launchpad.net/gnuregex/+milestone/2.9)找到了GNU regex for win32源原创 2021-11-06 17:46:14 · 1415 阅读 · 7 评论 -
c++11:使用HowardHinnant/date.h解析ISO8601格式字符串,并解决时区问题
C++11提供了std::get_time函数用于解析时间格式字符串,解析成功后将时间保存在std::tm结构中。但是对于ISO8601标准中有毫秒精度的字符串比如('2014-11-12T19:12:14.505+0800')是不支持的。如何解析这种有毫秒精度的时间字符串呢?HowardHinnant/date通过stakoverflow上的这个贴子:《how do I parse an iso 8601 date (with optional milliseconds) to a struc原创 2021-09-23 13:33:34 · 1070 阅读 · 0 评论 -
c,c++:获取当前时区偏移
下面的实现计算当前时区与UTC时间的偏移,#include <stdio.h>#include <time.h>int main(){ // 获取系统时间 time_t _rt = time(NULL); // 系统时间转换为GMT时间 tm _gtm = *gmtime(&_rt); // 系统时间转换为本地时间 tm _ltm = *localtime(&_rt); printf("UTC: %s", asctime(&原创 2021-09-23 11:29:33 · 2880 阅读 · 0 评论 -
C++11:参照Java Observable实现观察者模式
Java中的观察者设计模式是个比较实用的设计模式,可以用于数据自动更新,但是C++中并没提供现成的类实现,于是我参照Java的 java.util.Observable,将java代码翻译为C++代码。自己实现了一个observable::observable,用法与Java的Observable类一样。《JAVA设计模式之观察者模式》https://www.cnblogs.com/porotin/p/7825656.html实现代码整个代码只有一个文件observable.hpp,java源码原创 2021-09-16 17:08:44 · 298 阅读 · 0 评论 -
c++:error:locale::facet::_S_create_c_locale name not valid
最近在做一个linux-arm平台的项目时,遇到如如下错误error:locale::facet::_S_create_c_locale name not valid按照网上的找到所有答案都是要为主机添加语言支持,可是对于我们来说,程序是在客户的设备上跑的,要求用户添加特定的设置并不现实。通过反复查找,定位到下面的代码,是一个将字符串转大写的模板函数:template<typename E, typename TR = std::char_traits<E>, type原创 2021-03-24 12:51:49 · 2229 阅读 · 2 评论 -
c++11:计算时间差(毫秒)
C++11下计算时间差(毫秒)要用到chrono时间库,以下是示例代码,我从en.cppreference.com上抄来改的.#include <iostream>#include <iomanip>#include <vector>#include <numeric>#include <chrono> volatile int sink;int main(){ std::cout << std::fixed原创 2021-03-18 13:18:24 · 6549 阅读 · 1 评论 -
Windows NDK 编译openssl
关于NDK 编译openssl,网上找了不少文章,比如:《在windows上编译openssl供Android NDK使用》大都是基于这个github上的项目编译NDK openssl:https://github.com/guardianproject/openssl-android我也照着上面的文章顺利编译出了目标代码,但是因为编译出来的代码不是标准的安装目标结构,由于我需要用CMAKE交叉编译,所以这个项目编译出来的目标代码对于我并不方便使用。所以我自己下载了openssl的源码,并根据源码写原创 2021-01-31 21:34:16 · 1298 阅读 · 0 评论 -
MSVC/GCC/NDK:将二进制文件生成obj文件
如何将二进制文件作为数据添加到自己程序中?这是我最近遇到的问题,google上找到这两篇说得已经很清楚:《Embedding of binary data into programs》《Embedding Blobs in Binaries》一种方法是将想二进制文件生成c代码,与项目一起编译,这方法小的数据没问题,但如果二进制文件太大,生成的c代码更是巨大,增加编译器负担,好处就是完全没有跨平台问题。网上可以找到相关的工具(搜索 bin2c 或 bin2h)第二种方式就是用GNU的objcopy原创 2021-01-19 18:44:28 · 1033 阅读 · 0 评论 -
c++ thrift 库调试信息输出
thrift是一个跨平台的RPC框架,用了很久,但一直不知道如何输出它的内部日志,很长时间了,因为用不上,拿倒也相安无事。今天遇到thrift 底层socket通讯的问题,一直找不到原因,就把TSocket.cpp代码撸了一遍,才搞明白thrift库输出日志的方式。thrift有一个类型为apache::thrift::TOutput的全局变量GlobalOutput(定义在thrift/TOutput.h),通过调用其 setOutputFunction函数设置一个实现输出日志的回调函数,就可以让Th原创 2021-01-14 13:26:45 · 743 阅读 · 0 评论 -
C++11:string和wstring之间互转换
今天打算做string到wstring转换时发现以前早已经写过,已经忘记从哪里找来的了,贴出代码,以防再忘记。C++11后UTF8编码转换还真是方便#include <string>#include <locale>#include <codecvt> // convert string to wstring inline std::wstring to_wide_string(const std::string& input) { std::w原创 2020-12-12 11:06:43 · 4281 阅读 · 3 评论 -
eRPC:通过实现双向请求的串行通讯传输(dual serial transport)支持client/server混合运行
Dual serial transport概述eRPC 的默认的设计模型是简单的主从模式,也就是设备A上运行服务,另一个设备B主动发起请求调用A的服务,但在实际的应用中,我们需要双向的请求,也就是说设备A,设备B互为主从,两台设备上都会运行服务供对方调用。在这种模式下,原有的串行通讯传输(SerialTransport)实现就不能满足要求,因为设备接收到的数据无法知道是给server的请求(Requst),还是给client的响应(Response)。如果要实现上述的双向请求并不复杂,只要修改串行通讯原创 2020-11-16 18:30:03 · 1579 阅读 · 0 评论 -
cygwin下编译报错 `addrinfo hints‘ has incomplete type and cannot be defined
今天在cygwin下编译一个linux项目时报了类似下面的错误:server.cpp:20: error: aggregate `addrinfo hints' has incomplete type and cannot be definedserver.cpp:25: error: `AI_PASSIVE' was not declared in this scopeserver.cpp:27: error: `getaddrinfo' was not declared in this scope原创 2020-10-22 14:20:37 · 2795 阅读 · 0 评论 -
C++11模版元编程:如何判断一个类型是完整类型(complete type)
什么是完整类型(complete type)?要明白这个概念不如先从不完整类型(incomplete type)开始.简单说,如果在编译期编译器能计算出一个类型的size,那么它就是一个完整类型,否则就是不完整类型。比如如下的向前声明,编译器遇到它时,并无法判断student这个类型有占用多大的空间,所以它就是一个不完整类型:struct student *ps;当编译器遇到stude...原创 2020-04-25 18:32:51 · 1543 阅读 · 1 评论 -
erpc(EmbeddedRPC)入门笔记
RPC最近在忙一个IOT设备的项目,想设计一个通信系统通过串口控制设备(freertos)的运行。按照传统的设计思路,先要定义一套串口通信协议,在这套协议中传输层协议、应用层协议一个都不能少。每一层协议都要自己实现。数据编码/解码,数据校验,容错,这些非常基础的东西都要自己实现。等这些协议都实现了,才是能开始设计真正的业务逻辑。和同事商议后,一致认为要是照这么干,黄花菜都凉了。我们的生命不能...原创 2020-04-18 11:53:26 · 6723 阅读 · 0 评论 -
c++11:如何判断std::function对象相同?
我们知道std::function的实质就是个函数指针,但在c++11中std::function并没有实现操作符==(要到C++20才实现),所以我们无法使用==操作符来判断两个std::function对象是否相等,虽然我们明明知道它就是个指针。但我还是要判断啊,怎么办?仔细研究了std::function的定义,找到了这个 target()函数,c++11标准的官方定义就是返回函数指针,...原创 2020-04-06 18:24:21 · 4880 阅读 · 3 评论 -
c++11:枚举类型(enum)的前向声明(forward declaration)
在C++11之前,C++标准是不支持枚举类型的前向声明的。我说出这个结论,肯定有用msvc的童鞋不愿意了:口胡,MSVC明明就可以对枚举类型前向声明,下面这样的前向声明在MSVC下好好的,没有任何问题。enum E;是哦,你说的对,MSVC下上面的写法的确是没问题,那因为MSVC提供了这个特征,但放在gcc下编译试试,立即报错:use of enum E without previous...原创 2020-03-25 14:45:48 · 8012 阅读 · 2 评论 -
NV21转RGB或BGR的java实现和C实现
NV21是android平台摄像设备输出的标准格式,经常需要将它转为RGB或BGR格式,以下是NV21格式图像矩阵转为RGB/BGR的实现代码,代码在windows/linux/android平台测试通过.NV21格式的具体定义参见: 《YUV(NV21)图像数据到RGB颜色空间的转换》关于YUV与RGB的转换网上有很多文章,参见:《YUV与RGB互转各种公式》java实现 /** ...原创 2020-03-07 17:53:41 · 2039 阅读 · 2 评论 -
C++11 gcc升级到5.2.0后报错:/usr/lib64/libstdc++.so.6: version 'GLIBCXX_3.4.17' not found
我的linux操作系统为centos6.5,为了能编译C++11程序,需要对gcc编译器进行升级(centos6.5默认安装的gcc编译器是4.4.7,支持C++11需要至少4.8.1)到gcc5.2.0,参照《【Linux】CentOS6.5 gcc升级方式》对编译器进行了升级,耗时两个多小时。 等编译升级就绪,编译了C++11的代码,运行时,报错: /usr/lib64/libstdc++原创 2015-12-21 11:53:47 · 2603 阅读 · 0 评论 -
C++11 元编程(meta-programming)判断T是否有==操作符
前几天看了《C++11之美》受到一些启发,想到可以通过判断一个类型是否有指定的操作符(比如==,>=)。 基本的原理与文中的差不多,利用SFINAE原则,通过返回类型后置来推断表达式的类型,推断的过程中利用declval,它可以获取类型的右值引用,以便来调用==操作符,这个过程是在编译期完成的。 如果通过==操作符比较declval的右值引用成功了,则会继续推断逗号表达式的类型,最终推断的函数返原创 2015-12-09 09:43:29 · 1489 阅读 · 1 评论 -
C++11 JNI开发中RAII的应用(三)--JavaClassMirror
以下是我以前写的将一个C++对象转成java对象的函数toJCodeBean。static jobject toJCodeBean(JNIEnv* env, const code_bean& bean) { auto code_bean_class =jni_utilits::raii_FindClass_LocalRef("Lnet/gdface/facedbsdk/local/CodeC原创 2015-12-03 16:56:59 · 921 阅读 · 1 评论 -
C++11 JNI开发中RAII的应用(二)--JNI函数封装
在上一节《C++11 JNI开发中RAII的应用(一)》中我们已经有了一些基本的RAII封装工具,本节就简单了,就是根据需要把一些常用的JNIEnv函数封装成更方便使用的模板函数。raii_NewGlobalRefraii_NewGlobalRef函数顾名思义,就是封装JNIEnv::NewGlobalRef,将一个本地引用的jobject转为全局引用封装在raii_var中。 /* 封装JN原创 2015-12-03 15:41:49 · 1739 阅读 · 1 评论 -
C++11 在析构函数中执行lambda表达式(std::function)捕获this指针的陷阱
lambda表达式是C++11最重要也最常用的一个特性之一。lambda来源于函数式编程的概念,也是现代编程语言的一个特点。 关于lambda表达式的概念并不是本文的重点,网上可以找到无数的写得极好的文章介绍它。我想说的是善用lambda表达式,将给C++编程带来极大的便利,这是本人最近学习C++11以来真实深切的感受,但是有时候误用lambda表达式也会给编程带来极大的隐患,本文以最近的经历说明原创 2015-12-03 09:08:51 · 8924 阅读 · 1 评论 -
C++11 JNI开发中RAII的应用(一)--制作基础工具
最近项目C++底层代码写完了,开始做java与底层代码的接口部分,就涉及到JNI编程,我这是第一次写JNI代码,看了很多资料,得到一个印象:JNI开发本身不复杂,但如果操作不慎,很容易造成内存泄露参见《jni 内存泄露》,而且最容易被忽视的就是本地引用(LocalReference)造成的内存泄露。 按照oracle官方对的文档 《Java Native Interface Specificat原创 2015-12-02 14:27:02 · 1269 阅读 · 0 评论 -
C++11 你真的会用迭代器(iterator)么?
C++ STL提供了丰富的标准容器(Container)对象(vector,array,queue,list,set,unordered_map/set…),让我们可以根据需求选择不同的容器管理各种类型的数据。说到使用容器,不用迭代器(iterator)是不可能的,所有的容器对象都根据容器的特点都提供了类似但不同的iterator,用于访问容器中的数据。迭代器(iterator)循环一般来说,如果要原创 2015-11-22 09:35:15 · 10501 阅读 · 0 评论