C语言用awtk开发界面访问http接口

AWTK全称为Toolkit AnyWhere,是ZLG倾心打造的一套基于C语言开发的GUI框架。旨在为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的GUI引擎,并支持跨平台同步开发,一次编程,终生使用。

1. 初识AWTK | AWStudio社区版

看官网介绍可以免费用,唯一麻烦的就是需要注册账户,给key默认可以绑定3台机器

https://awtk.zlg.cn/注册账户后下载开发工具 https://awtk.zlg.cn/awstudio/download.html

安装包有win和linux,其他平台可能需要源码安装,就在deepinlinux20.9环境试了一下

按照例子建了一个空工程,加了按钮能切换语言,能读写控件值(text label),顺便加一下通过curl访问http接口的实例吧

首先安装curl库

sudo apt-get install libcurl4-openssl-dev

引用头文件

#include <curl/curl.h>

在编译C/C++程序时,添加以下链接选项,默认库在 /usr/lib/x86_64-linux-gnu/libcurl.so.4.5.0

-lcurl

在awtk里是配置sconstruct,将so库放在本项目里,再awtk的ide里编译调试都可以了

CUSTOM_WIDGET_LIBS = [{
		"root" : '3rd/curl',     # 第三方库路径,支持绝对路径和相对路径。
		'shared_libs': ['curl'], # 引用的动态库名称,动态库文件必须放在 root/bin 目录下。
		'static_libs': []       # 引用的静态库名称,静态库文件必须放在 root/lib 目录下。
	  }]

awtk的ide没有发布菜单,需要自己再工程根目录运行发布打包命令

python ./scripts/release.py

会将发布文件放到 ./release文件夹,这才是正规发布包内容

访问http接口一般返回json字符串,网上有c语言解析json

c操作json数据_json转为二进制c库-CSDN博客

本工程用awtk开发,可以用awtk自带的,更简洁

#include "conf_io/conf_json.h"

tk_object_t* doc = conf_json_load("awtk1.json", TRUE);
	printf("isSuccess:%d\n", tk_object_get_prop_bool(doc, "isSuccess",TRUE));
	char buf[128]={0};
	sprintf(buf,"%s",tk_object_get_prop_str(doc, "data"));
	printf("data:%s\n", buf);
	widget_set_text_utf8(edit, buf);
	TK_OBJECT_UNREF(doc);

得到一个比较长字符串,为了方便显示,每10个字符加个空格显示

widget_t* target = WIDGET(e->target);
	char buf[128]={0};
	char newbuf[128]={0};
	widget_get_text_utf8(target, buf, sizeof(buf)-1);
	printf("data = %s\n", buf);
	int i,j,t;
	j=strlen(buf);
	if(j>30){
		t=0;
		for(i=0;i<j;i++){			
			if(i>0 && (0==(i%10))){
				newbuf[t]=' ';
				t++;
			}
			newbuf[t]=buf[i];
			t++;
		}
		printf("newbuf: %s \n",newbuf);
		widget_set_text_utf8(label, newbuf);
	}

最后也记录一下curl的2种get调用(直接保存成文件和回调保存到字符串)

#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <string.h>
#include <unistd.h>
#include "conf_io/conf_json.h"
#include <ctype.h>
#define _XOPEN_SOURCE
#define __USE_XOPEN

struct MemoryStruct {
	char *memory;
	size_t size;
 
};
FILE *file;
widget_t* edit;
widget_t* label;
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{ 
	size_t realsize = size * nmemb;
	struct MemoryStruct *mem = (struct MemoryStruct*) userp;
	mem->memory = realloc(mem->memory, mem->size + realsize + 1);
	if (mem->memory == NULL) { 
		/* out of memory! */ 
		printf("not enough memory (realloc returned NULL)\n"); 
		return 0; 
	} 
	memcpy(&(mem->memory[mem->size]), contents, realsize);
	mem->size += realsize;
	mem->memory[mem->size] = 0;
	printf("get size %ld\n %s \n",mem->size , mem->memory);
	file=fopen("awtk1.json","w");
	fputs(mem->memory,file);
	fclose(file);
	tk_object_t* doc = conf_json_load("awtk1.json", TRUE);
	printf("isSuccess:%d\n", tk_object_get_prop_bool(doc, "isSuccess",TRUE));
	char buf[128]={0};
	sprintf(buf,"%s",tk_object_get_prop_str(doc, "data"));
	printf("data:%s\n", buf);
	widget_set_text_utf8(edit, buf);
	TK_OBJECT_UNREF(doc);
	return realsize; 
}
 
int httpsget(void) 
{ 
	CURL *curl = NULL;
	CURLcode res;
	struct MemoryStruct chunk;
	chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
	chunk.size = 0; /* no data at this point */
	curl_global_init(CURL_GLOBAL_ALL);
	/* get a curl handle */
	curl = curl_easy_init();
	if (!curl) {
		return -1;
	} 
	/*设置easy handle属性*/
	/* specify URL */
	curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
	curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.64.251:8080/api/jc5000/getVersion");
	/* Define our callback to get called when there's data to be written */
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
	/* Set a pointer to our struct to pass to the callback */
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
	/* set commom option */
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
	/*执行数据请求*/
	res = curl_easy_perform(curl); 
	if (res != CURLE_OK) {
		fprintf(stderr, "res=%d curl_easy_perform() failed: %s\n",res,curl_easy_strerror(res));
	} 
// 释放资源
	free(chunk.memory);
	curl_easy_cleanup(curl);
	curl_global_cleanup();
	return 0;
}


int gethttptofile() {
    printf("Hello, gethttptofile!\n"); 
    //1、curl全局初始化,初始化libcurl库(只能调用一次)
    //CURL_GLOBAL_ALL尽可能初始化一切(除了CURL_GLOBAL_ACK_EINTR)
    //CURL_GLOBAL_WIN32表示libcurl会初始化winsock库,如果失败则无法使用socket,windows系统专用
    //CURL_GLOBAL_SSL初始化SSL,(不初始化可能无法使用https)
    //CURL_GLOBAL_DEFAULT初始WIN32和SSL
    //CURL_GLOBAL_ACK_EINTR设置此标志后,curl将在连接或等待数据时确认EINTR条件。否则,curl会等待直到完全超时。(在7.30.0中添加)
    CURLcode init = curl_global_init(CURL_GLOBAL_ALL);
    if(init!=CURLE_OK){
        printf("curl全局初始化失败!\n");
        exit(1);
    } 
    //2、初始化curl,返回CURL句柄
    CURL *curl = (struct CURL *)curl_easy_init();
    if(curl==NULL){
        printf("初始化CURL失败!\n");
        exit(1);
    } 
    //3、设置option,各种curl参数的
    curl_easy_setopt(curl,CURLOPT_URL,"http://192.168.64.251:8080/test/getAppVersion");
     //设置保存位置,使用临时文件或保存到fopen中
    //FILE *
		file=fopen("awtk1.log","w");
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
    //各option
//    1.CURLOPT_URL
//    设置访问URL
//    2.CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
//    通过设定一个回调函数,执行libcurl在接受到数据后用户想进行的操作,通常函数多做数据保存的功能,如处理下载文件。CURLOPT_WRITEDATA 用于表明CURLOPT_WRITEFUNCTION函数中的stream指针的来源,说白了就是设定回调函数的第四个参数的数据类型。回调函数原型为:size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
//    3.CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA
//    通过设定一个回调函数,执行libcurl在接受到http头数据后用户想进行的操作。CURLOPT_WRITEDATA 传递指针给libcurl,该指针表明CURLOPT_HEADERFUNCTION 函数的stream指针的来源。回调函数原型为 size_t function( void *ptr, size_t size,size_t nmemb, void *stream);
//    4.CURLOPT_READFUNCTION CURLOPT_READDATA
//    libCurl需要读取数据传递给远程主机时将调用CURLOPT_READFUNCTION指定的函数,函数原型是:size_t function(void *ptr, size_t size, size_t nmemb,void *stream). CURLOPT_READDATA 表明CURLOPT_READFUNCTION函数原型中的stream指针来源,说白了就是设定回调函数的第四个参数的数据类型。
//    5.CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
//    跟数据传输进度相关的参数。CURLOPT_PROGRESSFUNCTION 指定的函数正常情况下每秒被libcurl调用一次,为了使CURLOPT_PROGRESSFUNCTION被调 用,CURLOPT_NOPROGRESS必须被设置为false,CURLOPT_PROGRESSDATA指定的参数将作为 CURLOPT_PROGRESSFUNCTION指定函数的第一个参数
//    6.CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
//    CURLOPT_TIMEOUT 用于设置传输时间,CURLOPT_CONNECTIONTIMEOUT 设置连接等待时间
//    7.CURLOPT_FOLLOWLOCATION
//    设置重定位URL
//    CURLOPT_RANGE: CURLOPT_RESUME_FROM:
//    断点续传相关设置。CURLOPT_RANGE 指定char *参数传递给libcurl,用于指明http域的RANGE头域,例如:
//    表示头500个字节:bytes=0-499
//    表示第二个500字节:bytes=500-999
//    表示最后500个字节:bytes=-500
//    表示500字节以后的范围:bytes=500-
//                       第一个和最后一个字节:bytes=0-0,-1
//    同时指定几个范围:bytes=500-600,601-999
//    CURLOPT_RESUME_FROM 传递一个long参数给libcurl,指定你希望开始传递的偏移量。
//    8.CURLOPT_UPLOAD:
//    如果第三个参数被设置为1的话,就是让libcurl做好上传的准备。如果传输协议是http的话,uoload就是发送put。
//    9. CURLOPT_SSL_VERIFYPEER:
//    第三个参数的缺省值为1.该函数多用于设定curl忽略对网站证书的检查(不管忽略不忽略,curl都是检查的)。
//    10.CURLOPT_VERBOSE
//    相当厉害的一个参数,可以向控制台(默认)输出curl接受和发送的数据,输出流可以重定向。
//    11.CURLOPT_HTTPGET
//    将curl向服务器交互数据的方式改变为get 
    //4、执行curl的各种操作的请求
    CURLcode curLcode = curl_easy_perform(curl);
    if(curLcode!=CURLE_OK){
        printf("curl请求失败:%d!\n",curLcode);
        exit(1);
    }
//    perform错误码说明:
//    1.CURLE_OK
//    任务完成一切都好
//    2.CURLE_UNSUPPORTED_PROTOCOL
//    不支持的协议,由URL的头部指定
//    3.CURLE_COULDNT_CONNECT
//    不能连接到remote 主机或者代理
//    4.CURLE_REMOTE_ACCESS_DENIED
//    访问被拒绝
//    5.CURLE_HTTP_RETURNED_ERROR
//    Http返回错误
//    6.CURLE_READ_ERROR
//    读本地文件错误 
    //5、读取请求响应的信息
    long totalTime;
    curLcode=curl_easy_getinfo(curl,CURLINFO_TOTAL_TIME,&totalTime);
    if(curLcode!=CURLE_OK){
        printf("curl获取信息失败:%d!\n",curLcode);
    }
    printf("CURLINFO_TOTAL_TIME:%ld!\n",totalTime);
//    getinfo参数
//    CURLINFO_EFFECTIVE_URL - 最后一个有效的URL地址
//    CURLINFO_HTTP_CODE - 最后一个收到的HTTP代码
//    CURLINFO_FILETIME - 远程获取文档的时间,如果无法获取,则返回值为"-1"
//    CURLINFO_TOTAL_TIME - 最后一次传输所消耗的时间
//    CURLINFO_NAMELOOKUP_TIME - 名称解析所消耗的时间
//    CURLINFO_CONNECT_TIME - 建立连接所消耗的时间
//    CURLINFO_PRETRANSFER_TIME - 从建立连接到准备传输所使用的时间
//    CURLINFO_STARTTRANSFER_TIME - 从建立连接到传输开始所使用的时间
//    CURLINFO_REDIRECT_TIME - 在事务传输开始前重定向所使用的时间
//    CURLINFO_SIZE_UPLOAD - 以字节为单位返回上传数据量的总值
//    CURLINFO_SIZE_DOWNLOAD - 以字节为单位返回下载数据量的总值
//    CURLINFO_SPEED_DOWNLOAD - 平均下载速度
//    CURLINFO_SPEED_UPLOAD - 平均上传速度
//    CURLINFO_HEADER_SIZE - header部分的大小
//    CURLINFO_HEADER_OUT - 发送请求的字符串
//    CURLINFO_REQUEST_SIZE - 在HTTP请求中有问题的请求的大小
//    CURLINFO_SSL_VERIFYRESULT - 通过设置CURLOPT_SSL_VERIFYPEER返回的SSL证书验证请求的结果
//    CURLINFO_CONTENT_LENGTH_DOWNLOAD - 从Content-Length: field中读取的下载内容长度
//    CURLINFO_CONTENT_LENGTH_UPLOAD - 上传内容大小的说明
//    CURLINFO_CONTENT_TYPE - 下载内容的Content-Type:值,NULL表示服务器没有发送有效的Content-Type:header
    //6、清理curl句柄
    curl_easy_cleanup(curl);
    //7、清理全局配置(只能调用一次)
    curl_global_cleanup();
		fclose(file); 
		file=fopen("awtk1.log","r");
    //8、操作文件内容
    //流指针移动到末尾
    fseek(file,0,SEEK_END);
    //返回当前流指针位置
    const long i = ftell(file);
    printf("文件长度:%ld!\n",i);
    //计算完毕记得把流指针归位
    rewind(file);
    //申请一块能装下整个文件内容的内存区域
    char *a = (char *) malloc(i);
    //fgets(a, i+1,file);
		fread(a, 1,i,file);
    printf("当前文件内容:%s \n",a); 
    //记得释放申请的内存区域
    free(a);
    //关闭临时文件
    fclose(file); 
    return 0;
}
相关推荐
wangjing_05224 小时前
C语言练习.if.else语句.strstr
c语言·开发语言
时光の尘7 小时前
C语言菜鸟入门·关键字·int的用法
c语言·开发语言·数据结构·c++·单片机·链表·c
Edward-tan7 小时前
c语言数据结构与算法--简单实现线性表(顺序表+链表)的插入与删除
c语言·开发语言·链表
武昌库里写JAVA7 小时前
一文读懂Redis6的--bigkeys选项源码以及redis-bigkey-online项目介绍
c语言·开发语言·数据结构·算法·二维数组
程序员与背包客_CoderZ8 小时前
C++设计模式——Abstract Factory Pattern抽象工厂模式
c语言·开发语言·c++·设计模式·抽象工厂模式
Mcworld85710 小时前
C语言:strcpy
c语言·开发语言
人才程序员10 小时前
详解Qt QStorageInfo 存储信息类
c语言·开发语言·c++·后端·qt·界面
ZHOUPUYU10 小时前
最新‌VSCode保姆级安装教程(附安装包)
c语言·开发语言·c++·ide·windows·vscode·编辑器
爱学嵌入式的菜鸟10 小时前
Linux应用编程(C语言编译过程)
linux·c语言·ubuntu
Best_Me0711 小时前
快速排序算法-C语言
c语言·算法·排序算法