C语言
cjzcjl
客户端一片哀嚎……
展开
-
JNI踩坑日记——突发脑残,用正负值判断地址是否正确
最近自己写的一个库,C返回一个内存地址后,Java通过long保存起来了,然后我很脑残地写了个if(地址 < 0)代表出错的代码(习惯思维害死人,因为想着地址都是正的,那么负的肯定有问题嘛)。然而java的long是有符号整数,导致地址一旦超过2^32次方就会报错,但实际上只是返回的8个字节的地址值最高位为1,是可用的地址来的。所以C返回给Java的内存地址,用long可以确定保存把8个字节的数据完整保存,但千万不能拿它进行正负判断,首先地址本身就没有负值,最高位符号位也是用于地址表达而非符号表达的,原创 2020-11-25 17:56:58 · 260 阅读 · 0 评论 -
安卓应用开发中通过JNI使用虚拟内存节约物理内存的一个例子
承接上文:《一种基于linux mmap特性的应用层虚拟内存工具的编写》java文件先编写JNI文件作为使用之前编写的工具的桥梁:#include "stdio.h"#include "stdlib.h"#include <string.h>#include <jni.h>#include "android/log.h"#include "mmapVirtualMemoryUtil.c"static const char *TAG = "mmapVi.原创 2020-07-29 16:53:38 · 251 阅读 · 0 评论 -
一种基于linux mmap特性的应用层虚拟内存工具的编写
为了方便一些对时间不敏感的大数据块的存放,尤其是在JNI环境中避免系统OOM,我打算给予MMAP做一套虚拟内存工具:首先来想一下申请连续块时的各种情况,方便编写仿malloc函数,各种增删情况如图:每个块开头用一个long来保存块总大小,寻找空间时见到这个标记即可立即跳过相应区域,如果有多个空间块则会因为连续踩到块大小标记产生连续跳跃,而当没有踩到该标记时——即内容为0时,逐地址遍历是否满足空间要求(一个long + 用户要求的大小)的地址内容都为0,是的话则使用该空间,起始地址用long记录占原创 2020-07-27 18:35:56 · 201 阅读 · 0 评论 -
一种通过linux特性mmap节约内存的思想
最近一个JNI调用的库,需要一口气要一个高达1GB占用的二维数组去进行数据处理,此时如果手机的内存不足的话很容易导致我们的APP在使用该功能时OOM,但是这个第三方库我没有源码改不了,所以想了一下自己学过的知识,突然想到以前学Linux C编程的时候,可以用mmap把外存文件映射为一个内存地址,这样就可以不实际占用内存的情况下读取这个文件了,于是写了一个demo测试一下:#include "stdio.h"#include "stdlib.h"#include<sys/mman.h>原创 2020-07-27 11:24:37 · 482 阅读 · 0 评论 -
一种通过多线程快速插入ARGB到YUV图片的原创方法 C语言实现
利用之前写的颜色混合原理,在实现了ARGB转成YUV后,通过alpha值按比例混合原有的YUV值即可:颜色混合具体实现代码:fastYuvInsertBmp.c过程中我使用了一个循环做了个假的三色bmp,你可以用真的bmp代替进行测试。精华在那个双重循环里面,留个坑以后解释位置偏移原理:#include "stdio.h"#include "stdlib.h"#include "multiThread.c"#include <sys/time.h>struct p原创 2020-06-29 18:37:06 · 284 阅读 · 0 评论 -
利用多叉树(字典树)实现简单的快速搜索
今晚在公众号上看到一条题: 看到题目第一时间想到树,而且是多叉树。为什么呢? 首先说说为何不选择顺序表,我们来试想想,如果500万个单词放在顺序表上,不加索引而且乱序,那么搜索一个关键词为开头的单词的时间按最差算要500万次比较,简直疯狂。但是如果先按首字母a~z排序一次,并记住每个首字母的第一个单词在表格第几个位置,效率又要好些,如果第二个字母再排序一些再做索引...原创 2018-10-30 20:41:03 · 6404 阅读 · 1 评论 -
使用JNI调用其他.so库因函数名对不齐引起undefind reference的问题
在实现FrameBuffer快速局部刷新库的过程,我把一部分函数打包成了一个动态链接so库方便以后其他需要使用FrameBuffer的程序使用。可是在调用的时候却发生了一些奇怪的事情:我在so库中编写了一个void drawPixel(int offset, int color)函数,并且成功编译成了so库libdraw_dazzle.so。然后我使用JNI makeFile文件引入该库:...原创 2018-09-14 16:11:57 · 883 阅读 · 2 评论 -
FrameBuffer图形库工程1——理解FrameBuffer的逻辑结构
之前OpenGL做的白板在书写时有不跟手,图像延迟等的问题,在参考了其他公司的竞品的书写现象后发现,书写得快的竞品有几款都有覆盖系统UI的表现,这不是OpenGL能做到的事,更有点像以前上汇编课程(可惜啊,汇编几乎忘光了)直接修改系统显存显示内容的感觉。于是在使用OpenGL做了一个书写Demo后发现还是比不上他们指哪打哪的感觉之后(还是有点延迟感,即使FPS一直都是60帧),于是我...原创 2018-08-28 14:29:00 · 2438 阅读 · 0 评论 -
一种输入16进制字符串,转化成整数的算法
#include "stdio.h"#include "stdlib.h"int main() { char *s = malloc(100); int i; int data = 0; printf("input your hex string:"); scanf("%s", s); for(i = 0; i < strlen(s); i++) { if(s[i] ...原创 2018-11-06 13:57:47 · 1013 阅读 · 0 评论 -
一个JNI创建日期对象的例子,仅作参考
JNIEXPORT void JNICALL Java_com_cjz_mapscr_MapScreen_drawLines (JNIEnv *env, jobject thiz) { jclass clazz_date = (*env)->FindClass(env, "java/util/Date"); jmethodID mid_date = (*env)->GetMeth...原创 2018-11-20 16:06:26 · 316 阅读 · 0 评论 -
一种C语言创建超大二维数组的办法
最近需要写一套JNI来纪录整个屏幕的像素信息(9屏截屏),于是想创建一个二维数组方便快捷地进行保存,结果炸开了:基本可以百分百肯定是栈空间不足,但我又不想增加栈空间,那怎么办呢?其实还是有办法的。首先二维数组是什么呢?其实就是两部分组成,一个一维指针数组,然后数组里面的每个指针指向(保存)了一个唯一对应的定长数组的首地址而已。(同理,三维数组,就是三部分组成,第一部分是指向...原创 2018-11-17 15:43:39 · 7720 阅读 · 4 评论 -
一种一维数组或连续内存区转多维数组的方法
在C中创建的多维数组,其实本质上都是分配符合容量大小的一维数组,再分割成等份单位而成。除非使用堆空间动态分配则不适用:https://blog.csdn.net/cjzjolly/article/details/84189136例如数组int array[3][3],其实实际是想申请了9个单元的连续存储空间,然后新建3个指向该类型单元的指针的指针——例如本例子就是int array**,把...原创 2018-11-29 18:37:56 · 422 阅读 · 0 评论 -
一种不靠第三个变量交换变量值的办法(利用异或XOR)
原理:例如:a = 10 b = 01(二进制)a = 10 XOR 01 = 11b = 01 XOR 11 = 10a = 11 XOR 10 = 01最后a = 01, b = 10,两者的二进制值交换了。C代码:void swap(int *a, int *b){ *a ^= *b; *b ^= *a; *a ^= *b;} ...原创 2018-12-27 18:13:37 · 350 阅读 · 1 评论 -
循环赋值更快还是memcpy更快?
最近在优化白板书写提速的FrameBuffer库,发现有一个循环:void drawPixelRect(int x, int y, int width, int height, int* pixels) { int loc = y * FIXED_WIDTH + x; int i, j, k = 0; //int endLoc = (y + height) * FIXED_WIDTH ...原创 2019-04-29 19:31:58 · 7406 阅读 · 2 评论 -
一个Linux AF_UNIX socket通信的简单例子
服务端(接受内容):#include "stdio.h"#include "stdlib.h"#include "drawFbStruct.h"#include <sys/socket.h>#include <sys/types.h>#include <sys/un.h>#define new(Class) (Class*)malloc(si...原创 2019-09-23 12:06:29 · 1497 阅读 · 0 评论 -
C语言指针偏移技巧(也是一个要注意的坑)
在C语言中,每个地址实际上指向一个8bit的内存区,但如果某个内存区的地址使用一个明确的类型指针例如int*、long*来进行保 存,那么指针偏移时地址的偏移数以类型占的字节数为基本单位进行偏移,例如int *p变量+1的时候实际上跳过的是sizeof(int)的类型字节数的地址为单位进行跳跃——也就是跳跃4个地址,但如果是不确认类型的情况下使用void*来保存,则必须指定每次跳跃的准......原创 2018-08-27 17:56:59 · 31114 阅读 · 1 评论 -
用NDK(JNI)获取触摸事件
由于安卓触摸事件的分发略显缓慢,尤其是在快速移动时点密度的降低可能会导致绘制曲线的点变得稀薄,从而增加曲线的走样程度。因此我用了JNI + Linux C + NDK做了一套直接从底层设备获取触摸设备坐标信息的库。 一、编写C文件和MakeFile:/**getevent2.c**/#include<stdio.h>#include<stdlib.h>#...原创 2018-08-17 18:02:46 · 3050 阅读 · 7 评论 -
简单的链表存储和搜索例子(完整的增删查改)
#include "stdio.h"#include "stdlib.h"#include "string.h"//链表结点typedef struct Item ListItem;struct Item{ char *epc, *name; ListItem *next;};ListItem* creatList();ListItem* createItem(ch原创 2017-11-23 18:46:39 · 417 阅读 · 0 评论 -
C语言链表库(gcc、mingw编译通过,不支持VC6(因为VC6不支持变参函数))
头文件:LinkedList.h/************************************* * * 作者:陈杰柱 * * 2017年11月 * *原创 2017-12-12 15:32:14 · 365 阅读 · 0 评论 -
一种C语言变参函数、变参宏、利用void*传播多个参数、通过内存地址和struct匹配这个地址做内存而获得多个数据的混合例子
#include "stdio.h"#include "stdlib.h"#include "string.h"#define display(flag, msg) if(flag) printf("%s\n",msg)#define new(Class) (Class*)malloc(sizeof(Class))#define findMethodByObject(Object, M原创 2017-12-13 15:01:04 · 614 阅读 · 0 评论 -
利用JNI写的安卓串口读写框架
C代码如下:#include #include #include #include #include #include #include //#include "SerialPort.h"#include "android/log.h"static const char *TAG="serial_port";#define LOGI(fmt, args...) __an原创 2017-12-06 16:34:34 · 1287 阅读 · 1 评论 -
n叉树算法 完美成功版本
没有任何查书、没有任何上网查,全部纯手打,作为专业科思维训练。感觉非常有成就感!!!主要涉及单链表、双链表、链式队列、递归算法~直接贴代码吧:#include "stdio.h"#include "stdlib.h"struct childlist{ struct node *current_node; struct childlist *next; };struct node...原创 2018-02-27 12:17:23 · 655 阅读 · 0 评论 -
奇葩链表使用方法之 不用结构体来达成链表
如果不用结构体,用double类型变量,整数放内存区地址,小数点后用用户的值,是否也能构成链表咧?~发现完全是可行的#include "stdio.h"#include "stdlib.h"main(){ double *now,*head,*next; int i,temp; head = now = (double*)malloc(sizeof(double)); next ...原创 2018-02-27 12:24:09 · 727 阅读 · 0 评论 -
变量、指针、参数、数组、内存分配的关系和陷阱
陷阱1:传入一个无指针的指针变量作为形参,你是无办法往里面塞地址或内容的例子1:#include "stdlib.h"#include "stdio.h"void shit(char *p){ printf("p之前指向的地址是:%d\n",p); p= (char*)malloc(sizeof(char)); printf("p现在指向的地址是:%d\n...原创 2018-02-27 12:37:52 · 268 阅读 · 0 评论 -
递归和迭代的转化示例——非递归二叉树遍历的写法
一、递归式遍历: 递归十分适合于自相似(分形)类的数据结构。有些线性数据结构的递归可以改为尾递归使得递归栈帧不再累积。但非线性数据结构的递归由于每层的栈帧可能以不同的方式和参数调用自身,例如二叉树遍历的递归,每层函数栈里面有两次自我调用,不能该为尾递归,在极限情况下有爆栈可能。因此需要模仿函数栈的特性写出等效迭代代码。 二叉树后序递归逻辑结构如下: void re...原创 2018-02-27 13:31:54 · 474 阅读 · 0 评论 -
利用尾递归做链表倒置题
看到又一次知乎轮子哥说有次面试面到一个人说不出链表倒置(反转)的办法,觉得这个人的计算机底蕴不行没有招。所以自己用尾递归写一个试试,感觉挺好玩的。 先上流程图: 其实就是做一个函数,取相邻的两个结点,还有第二个结点的下一个的值,就可以将这两个结点进行翻转。执行完之后,再把第二个结点和刚刚保留的第二个结点的下一个结点。分别再输入到函数的第一个结点,和第二个结点中,反复操...原创 2018-02-25 14:01:09 · 699 阅读 · 0 评论 -
一种多叉树的例子
#include "stdio.h"#include "stdlib.h"#define new(Class) (Class*)malloc(sizeof(Class)) typedef struct node Node;struct node{ Node *next; Node *nextLayer; //有地址的话代表有下一层链表 int num;};//弄一...原创 2018-04-21 16:43:59 · 665 阅读 · 0 评论 -
n叉树(n有最大值)的数组形多叉树的先序递归遍历方法
#include "stdio.h"#include "stdlib.h"#define new(Class) (Class*)malloc(sizeof(Class)) typedef struct node Node;struct node{ Node *next[3]; char content;};Node* createTree(){ Node* A = n...原创 2018-05-04 16:04:14 · 733 阅读 · 0 评论 -
JNI——将JAVA字符串数组转化为char**(C字符数组的(字符串)数组)的一个例子
/**将JAVA字符串数组转C char字符数组(俗称字符串)的数组**/char** stringArrToCharArr(JNIEnv * env, jclass jc, jobjectArray strArray ){ jstring jstr; jsize len = (*env)->GetArrayLength(env, strArray); char *...原创 2018-05-18 11:18:30 · 1665 阅读 · 1 评论 -
一种简单的跨平台(Linux、Windows)多线程程序实现的例子
#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <time.h> #ifdef _WIN32 #include <windows.h> #include <direct.h> #include <...原创 2018-05-07 10:55:42 · 1955 阅读 · 2 评论 -
一种利用JNI实现的对象序列化存储库,使得JAVA序列化对象后可以存于内存区高速读写,并且不受JVM控制以避免OOM
本工程应用于一款安卓白板程序,因有读写速度需求,传统的序列化到磁盘的方式读写速度太慢,因此想到了利用C的特性写一个高速缓存,并继承实现了自己的inputStream和outputStream,用于暂存大规模多叉树和大体积对象。本工程的序列化对象的数据均使用一个整数作为标记进行区分,有需要的朋友可以修改本工程的实现以支持字符串标记。 本工程的JNI部分: 一、首先是M...原创 2018-06-27 19:49:29 · 598 阅读 · 0 评论 -
ARGB颜色快速取大对比度色(保留原本透明度)
项目中为了使对字体对比背景色可以产生较大差异,让字体随着背景色的变化不会出现看不清的情况,需要根据背景来更换字体颜色。设背景的颜色保存在一个ARGB int变量bgColor中,Alpha透明度、Red、Green、Blue均是255级变换(0x00~0xFF),对比色变换后颜色保存在textColor中,那么变换方式便是:int textColor = 0x00FFFFFF ^ bgCo...原创 2018-08-07 14:24:20 · 3136 阅读 · 0 评论 -
变参函数的使用方法一、标记加偏移地址法
笔记原创 2017-11-22 13:53:51 · 626 阅读 · 1 评论