C语言 动态库简单开发
动态库项目
- //简单的动态库开发----报文发送
- #define _CRT_SECURE_NO_WARNINGS
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- //定义上下文结构体
- typedef struct _SCK_HANDLE{
- //定义报文IP
- char ipaddress[];
- //定义报文端口
- char port[];
- //定义报文接受数组
- unsigned char * buf;
- //定义报文长度
- int buflen;
- }SCK_HANDLE;
- //初始化上下文
- _declspec(dllexport)
- int cltSocketInit(void **handle/*out*/){
- int ERRO_MSG = ;
- if (handle == NULL)
- {
- ERRO_MSG = ;
- printf("handle==NULL 报文初始化失败 erro msg:%d\n", ERRO_MSG);
- return ERRO_MSG;
- }
- //定义上下文指针
- SCK_HANDLE *shandle = NULL;
- //分配内存
- //详述:此处分配内存必须分配堆内存(malloc函数分配),这也正是malloc函数真正的用途所在
- //此处不可以分配栈内存,栈内存会被系统自动回收,但是报文的发送与接受所使用的上下文SCK_HANDLE,必须长时间存在
- //何时回收必须由用户决定,而不能随便的被回收
- //同样使用静态区也不合适,因为无法人为回收内存空间,必须等待电脑关机,综上所述,只能使用malloc函数分配内存
- shandle = (SCK_HANDLE *)malloc(sizeof(SCK_HANDLE));
- //重置内存空间
- memset(shandle, , sizeof(SCK_HANDLE));
- strcpy(shandle->ipaddress, "192.168.0.128");
- strcpy(shandle->port, "");
- *handle = shandle;
- return ERRO_MSG;
- }
- //客户端发报文
- _declspec(dllexport)
- int cltSocketSend(void *handle/*in*/, unsigned char *buf/*in*/, int buflen/*in*/){
- int ERRO_MSG = ;
- if (handle == NULL)
- {
- ERRO_MSG = ;
- printf("handle==NULL handle不可以为NULL erro msg :%d\n", ERRO_MSG);
- return ERRO_MSG;
- }
- if (buf == NULL)
- {
- ERRO_MSG = ;
- printf("buf==NULL buf不可以为NULL erro msg :%d\n", ERRO_MSG);
- return ERRO_MSG;
- }
- SCK_HANDLE *sh = NULL;
- sh = (SCK_HANDLE *)handle;
- //为报文字符开辟内存空间
- sh->buf = (char *)malloc(sizeof(char)*buflen);
- if (sh->buf == NULL)
- {
- ERRO_MSG = ;
- printf("sh->buf==NULL 内存分配失败 erro msg :%d\n", ERRO_MSG);
- return ERRO_MSG;
- }
- //给上下文中的报文字符赋值
- //memcpy()函数详解
- //函数原型
- //void *memcpy(void *dest, const void *src, size_t n);
- //功能
- //从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
- //所需头文件
- //C语言:#include<string.h>
- //C++:#include<cstring>
- //返回值
- //函数返回指向dest的指针。
- //说明
- //1.source和destin所指的内存区域可能重叠,但是如果source和destin所指的内存区域重叠, 那么这个函数并不能够确保source所在重叠区域在拷贝之前不被覆盖。而使用memmove可以用来处理重叠区域。函数返回指向destin的指针.
- //2.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
- //注意:source和destin都不一定是数组,任意的可读写的空间均可。
- memcpy(sh->buf, buf, buflen);
- sh->buflen = buflen;
- return ERRO_MSG;
- }
- //客户端收报文
- _declspec(dllexport)
- int cltSocketRev(void *handle/*in*/, unsigned char **buf/*out*/, int *buflen/*out*/){
- int ERRO_MSG = ;
- if (handle == NULL || buf == NULL || buflen == NULL)
- {
- ERRO_MSG = ;
- printf("handle == NULL || buf == NULL || buflen==NULL erro msg:%d\n", ERRO_MSG);
- return ERRO_MSG;
- }
- //定义临时上下文变量
- SCK_HANDLE *sh = NULL;
- sh = (SCK_HANDLE *)handle;
- //分配返回报文字符串内存
- char *cbuf = (char *)malloc(sizeof(char)*sh->buflen);
- memcpy(cbuf, sh->buf, sh->buflen);
- *buf = cbuf;
- *buflen = sh->buflen;
- //释放上下文中字符串数组的内存空间(至于具体应用还是看场景)
- if (sh->buf != NULL)
- {
- //释放内存
- free(sh->buf);
- //消除野指针
- sh->buf = NULL;
- }
- sh->buflen = ;
- return ERRO_MSG;
- }
- //客户端释放资源
- _declspec(dllexport)
- int cltSocketDestory(void **handle){
- int ERRO_MSG = ;
- if (handle == NULL)
- {
- ERRO_MSG = ;
- printf("handle==NULL%d\n", ERRO_MSG);
- return ERRO_MSG;
- }
- //转换类型
- SCK_HANDLE *sh = NULL;
- sh = (SCK_HANDLE *)(*handle);
- //判断字符串数组是否释放--严谨做法
- if (sh->buf!=NULL)
- {
- //释放内存
- free(sh->buf);
- //消除野指针
- sh->buf = NULL;
- //长度置零
- sh->buflen = ;
- }
- if (sh != NULL)
- {
- //释放内存
- free(sh);
- //消除野指针
- sh = NULL;
- }
- return ERRO_MSG;
- }
测试项目
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include"socketclientdll.h"
- void main()
- {
- int ret = ;
- //初始化报文
- void *handle = NULL;
- ret = cltSocketInit(&handle);
- if (ret==)
- {
- printf("报文初始化成功!\n");
- }
- //发送报文
- unsigned char *str = "1234567890qwertyuiop";
- int buflen = ;
- ret = cltSocketSend(handle, str, buflen);
- if (ret == )
- {
- printf("报文发送成功!\n");
- }
- unsigned char *str2 = NULL;
- int buflen2 = ;
- //接受报文
- ret = cltSocketRev(handle, &str2, &buflen2);
- if (ret == )
- {
- unsigned char *buf3 = (char *)malloc(sizeof(char)*);
- memset(buf3,,sizeof(char)*);
- memcpy(buf3, str2, );
- //strcpy(buf3, str2);
- printf("报文接受成功!\n");
- printf("接受报文:%s;报文长度是%d\n", buf3, buflen2);
- }
- //释放上下文
- cltSocketDestory(&handle);
- printf("%p\n", handle);
- system("pause");
- }
效果图
C语言 动态库简单开发的更多相关文章
- 通过实例简介python使用ctypes模块调用C语言动态库
看介绍python语言时,说它是胶水语言,可以调用其他语言.通过使用ctypes模块就可以调用C语言的动态库.下面先放上官方文档和几个比较好的博文. 1.官方文档:http://python.net/ ...
- C语言动态库和静态库的使用及实践
转自:https://www.cnblogs.com/CoderTian/p/5902154.html 1.C语言中的链接器 (1)每个 C 语言源文件被编译后生成目标文件,这些目标文件最终要被链接 ...
- Ubuntu下通过makefile生成静态库和动态库简单实例
本文转自http://blog.csdn.net/fengbingchun/article/details/17994489 Ubuntu环境:14.04 首先创建一个test_makefile_gc ...
- Android项目编译和使用C语言动态库(so库)
编译SO库 1.新建工程,建立jni目录用于放置c语言相关文件 2.编写Android.mk文件 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) ...
- c#: 界面多语言动态切换简单实现
终于有空整理下多语言实现思路.查阅已有方案,有用不同resx文件的,有每个控件动态设置的,有用反射去整的,颇为繁琐. 结合项目中实现方法,并做简化,实现通用的多语言切换方案,以做备忘. 它支持语言自定 ...
- Windows动态库学习心得
最近在工作中需要给项目组其他成员提供调用函数,决心抛弃以前“拷贝头文件/源文件”的简陋方法,采用动态库的方式对自己开发的接口进行模块化管理.因之前一直没有机会从事Windows动态库的开发,现借助这个 ...
- Windows静态库和动态库的创建和使用
偶们在实际的编程开发中,经常会遇到运行时无法找到某个DLL文件或者链接时无法找到某个LIB文件.然后,我们就开始乱GOOGLE一下,然后将VS2005的设置改变一下,或许就Ok了,我们将别人开发的DL ...
- Windows静态库和动态库的创建和使用(VS2005)
偶们在实际的编程开发中,经常会遇到运行时无法找到某个DLL文件或者链接时无法找到某个LIB文件.然后,我们就开始乱GOOGLE一下,然后将VS2005的设置改变一下,或许就Ok了,我们将别人开发的DL ...
- golang调用c动态库
golang调用c动态库 简介 golang调用c语言动态库,动态方式调用,可指定动态库路径,无需系统目录下 核心技术点 封装c动态库 go语言调用c代码 实例代码 封装c动态库 头文件 test_s ...
随机推荐
- xcode 设置快捷键 整行上下移动
设置整行代码上下移动:找到Xcode中的自带的配置文件:/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/ ...
- openstack kilo compute更新后报错IncompatibleObjectVersion: Version 1.2 of PciDeviceList is not supported
前几天在compute节点更新openstack的包后,发现报错IncompatibleObjectVersion: Version 1.2 of PciDeviceList is not suppo ...
- python super
http://hi.baidu.com/thinkinginlamp/item/3095e2f52c642516ce9f32d5 Python中对象方法的定义很怪异,第一个参数一般都命名为self(相 ...
- 【MySQL】MySQL忘记root密码解决方案
转眼间从实习到现在已经快两年了.两年的工作做遇到过很多很多的拦路虎,大部分也通过搜索引擎找到了解决的方案.奈何大脑不是硬盘,偶尔有的问题第二次遇到还是有点抓蒙...所以决定把这些东西记录在博客上.这样 ...
- 以前写的关于Linux C/C++的博客
以前在CU写的关于Linux C/C++的博客 http://blog.chinaunix.net/uid/25909722/cid-24318-list-1.html
- 第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息
第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...
- python 解析json loads dumps
认识 引用模块 重要函数 案例 排序 缩进参数 压缩 参考 认识 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于JavaScript(Standa ...
- I2C 总线协议
1.I2C协议 2条双向串行线,一条数据线SDA,一条时钟线SCL. SDA传输数据是大端传输,每次传输8bit,即一字节. 支持多主控(multimastering),任何时间点只能 ...
- VS2010 调试窗口一闪而过解决方法
若此时进行的操作是编译(F5),可先运行程序(Ctrl+F5),若仍然一闪而过,用下面方法解决. 方法一: 1.要有头文件cstdlib,在程序最后写一句(return之前)添加:system(&qu ...
- android自定义radiobutton样式文字颜色随选中状态而改变
主要是写一个 color selector 在res/建一个文件夹取名color res/color/color_radiobutton.xml <selector xmlns:android= ...