动态库项目

  1. //简单的动态库开发----报文发送
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. #include<string.h>
  6.  
  7. //定义上下文结构体
  8. typedef struct _SCK_HANDLE{
  9. //定义报文IP
  10. char ipaddress[];
  11. //定义报文端口
  12. char port[];
  13. //定义报文接受数组
  14. unsigned char * buf;
  15. //定义报文长度
  16. int buflen;
  17. }SCK_HANDLE;
  18.  
  19. //初始化上下文
  20. _declspec(dllexport)
  21. int cltSocketInit(void **handle/*out*/){
  22. int ERRO_MSG = ;
  23. if (handle == NULL)
  24. {
  25. ERRO_MSG = ;
  26. printf("handle==NULL 报文初始化失败 erro msg:%d\n", ERRO_MSG);
  27. return ERRO_MSG;
  28. }
  29. //定义上下文指针
  30. SCK_HANDLE *shandle = NULL;
  31. //分配内存
  32. //详述:此处分配内存必须分配堆内存(malloc函数分配),这也正是malloc函数真正的用途所在
  33. //此处不可以分配栈内存,栈内存会被系统自动回收,但是报文的发送与接受所使用的上下文SCK_HANDLE,必须长时间存在
  34. //何时回收必须由用户决定,而不能随便的被回收
  35. //同样使用静态区也不合适,因为无法人为回收内存空间,必须等待电脑关机,综上所述,只能使用malloc函数分配内存
  36. shandle = (SCK_HANDLE *)malloc(sizeof(SCK_HANDLE));
  37. //重置内存空间
  38. memset(shandle, , sizeof(SCK_HANDLE));
  39. strcpy(shandle->ipaddress, "192.168.0.128");
  40. strcpy(shandle->port, "");
  41. *handle = shandle;
  42. return ERRO_MSG;
  43. }
  44. //客户端发报文
  45. _declspec(dllexport)
  46. int cltSocketSend(void *handle/*in*/, unsigned char *buf/*in*/, int buflen/*in*/){
  47. int ERRO_MSG = ;
  48. if (handle == NULL)
  49. {
  50. ERRO_MSG = ;
  51. printf("handle==NULL handle不可以为NULL erro msg :%d\n", ERRO_MSG);
  52. return ERRO_MSG;
  53. }
  54. if (buf == NULL)
  55. {
  56. ERRO_MSG = ;
  57. printf("buf==NULL buf不可以为NULL erro msg :%d\n", ERRO_MSG);
  58. return ERRO_MSG;
  59. }
  60. SCK_HANDLE *sh = NULL;
  61. sh = (SCK_HANDLE *)handle;
  62. //为报文字符开辟内存空间
  63. sh->buf = (char *)malloc(sizeof(char)*buflen);
  64. if (sh->buf == NULL)
  65. {
  66. ERRO_MSG = ;
  67. printf("sh->buf==NULL 内存分配失败 erro msg :%d\n", ERRO_MSG);
  68. return ERRO_MSG;
  69. }
  70. //给上下文中的报文字符赋值
  71. //memcpy()函数详解
  72. //函数原型
  73. //void *memcpy(void *dest, const void *src, size_t n);
  74. //功能
  75. //从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
  76. //所需头文件
  77. //C语言:#include<string.h>
  78. //C++:#include<cstring>
  79. //返回值
  80. //函数返回指向dest的指针。
  81. //说明
  82. //1.source和destin所指的内存区域可能重叠,但是如果source和destin所指的内存区域重叠, 那么这个函数并不能够确保source所在重叠区域在拷贝之前不被覆盖。而使用memmove可以用来处理重叠区域。函数返回指向destin的指针.
  83. //2.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
  84. //注意:source和destin都不一定是数组,任意的可读写的空间均可。
  85. memcpy(sh->buf, buf, buflen);
  86. sh->buflen = buflen;
  87. return ERRO_MSG;
  88. }
  89. //客户端收报文
  90. _declspec(dllexport)
  91. int cltSocketRev(void *handle/*in*/, unsigned char **buf/*out*/, int *buflen/*out*/){
  92. int ERRO_MSG = ;
  93. if (handle == NULL || buf == NULL || buflen == NULL)
  94. {
  95. ERRO_MSG = ;
  96. printf("handle == NULL || buf == NULL || buflen==NULL erro msg:%d\n", ERRO_MSG);
  97. return ERRO_MSG;
  98. }
  99. //定义临时上下文变量
  100. SCK_HANDLE *sh = NULL;
  101. sh = (SCK_HANDLE *)handle;
  102. //分配返回报文字符串内存
  103. char *cbuf = (char *)malloc(sizeof(char)*sh->buflen);
  104. memcpy(cbuf, sh->buf, sh->buflen);
  105. *buf = cbuf;
  106. *buflen = sh->buflen;
  107. //释放上下文中字符串数组的内存空间(至于具体应用还是看场景)
  108. if (sh->buf != NULL)
  109. {
  110. //释放内存
  111. free(sh->buf);
  112. //消除野指针
  113. sh->buf = NULL;
  114. }
  115. sh->buflen = ;
  116. return ERRO_MSG;
  117. }
  118. //客户端释放资源
  119. _declspec(dllexport)
  120. int cltSocketDestory(void **handle){
  121. int ERRO_MSG = ;
  122. if (handle == NULL)
  123. {
  124. ERRO_MSG = ;
  125. printf("handle==NULL%d\n", ERRO_MSG);
  126. return ERRO_MSG;
  127. }
  128. //转换类型
  129. SCK_HANDLE *sh = NULL;
  130. sh = (SCK_HANDLE *)(*handle);
  131. //判断字符串数组是否释放--严谨做法
  132. if (sh->buf!=NULL)
  133. {
  134. //释放内存
  135. free(sh->buf);
  136. //消除野指针
  137. sh->buf = NULL;
  138. //长度置零
  139. sh->buflen = ;
  140. }
  141. if (sh != NULL)
  142. {
  143. //释放内存
  144. free(sh);
  145. //消除野指针
  146. sh = NULL;
  147. }
  148. return ERRO_MSG;
  149. }

测试项目

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include"socketclientdll.h"
  6.  
  7. void main()
  8. {
  9. int ret = ;
  10. //初始化报文
  11. void *handle = NULL;
  12. ret = cltSocketInit(&handle);
  13. if (ret==)
  14. {
  15. printf("报文初始化成功!\n");
  16. }
  17. //发送报文
  18. unsigned char *str = "1234567890qwertyuiop";
  19. int buflen = ;
  20. ret = cltSocketSend(handle, str, buflen);
  21. if (ret == )
  22. {
  23. printf("报文发送成功!\n");
  24. }
  25. unsigned char *str2 = NULL;
  26. int buflen2 = ;
  27. //接受报文
  28. ret = cltSocketRev(handle, &str2, &buflen2);
  29. if (ret == )
  30. {
  31. unsigned char *buf3 = (char *)malloc(sizeof(char)*);
  32. memset(buf3,,sizeof(char)*);
  33. memcpy(buf3, str2, );
  34. //strcpy(buf3, str2);
  35. printf("报文接受成功!\n");
  36. printf("接受报文:%s;报文长度是%d\n", buf3, buflen2);
  37. }
  38. //释放上下文
  39. cltSocketDestory(&handle);
  40. printf("%p\n", handle);
  41. system("pause");
  42. }

效果图

C语言 动态库简单开发的更多相关文章

  1. 通过实例简介python使用ctypes模块调用C语言动态库

    看介绍python语言时,说它是胶水语言,可以调用其他语言.通过使用ctypes模块就可以调用C语言的动态库.下面先放上官方文档和几个比较好的博文. 1.官方文档:http://python.net/ ...

  2. C语言动态库和静态库的使用及实践

    转自:https://www.cnblogs.com/CoderTian/p/5902154.html  1.C语言中的链接器 (1)每个 C 语言源文件被编译后生成目标文件,这些目标文件最终要被链接 ...

  3. Ubuntu下通过makefile生成静态库和动态库简单实例

    本文转自http://blog.csdn.net/fengbingchun/article/details/17994489 Ubuntu环境:14.04 首先创建一个test_makefile_gc ...

  4. Android项目编译和使用C语言动态库(so库)

    编译SO库 1.新建工程,建立jni目录用于放置c语言相关文件 2.编写Android.mk文件 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) ...

  5. c#: 界面多语言动态切换简单实现

    终于有空整理下多语言实现思路.查阅已有方案,有用不同resx文件的,有每个控件动态设置的,有用反射去整的,颇为繁琐. 结合项目中实现方法,并做简化,实现通用的多语言切换方案,以做备忘. 它支持语言自定 ...

  6. Windows动态库学习心得

    最近在工作中需要给项目组其他成员提供调用函数,决心抛弃以前“拷贝头文件/源文件”的简陋方法,采用动态库的方式对自己开发的接口进行模块化管理.因之前一直没有机会从事Windows动态库的开发,现借助这个 ...

  7. Windows静态库和动态库的创建和使用

    偶们在实际的编程开发中,经常会遇到运行时无法找到某个DLL文件或者链接时无法找到某个LIB文件.然后,我们就开始乱GOOGLE一下,然后将VS2005的设置改变一下,或许就Ok了,我们将别人开发的DL ...

  8. Windows静态库和动态库的创建和使用(VS2005)

    偶们在实际的编程开发中,经常会遇到运行时无法找到某个DLL文件或者链接时无法找到某个LIB文件.然后,我们就开始乱GOOGLE一下,然后将VS2005的设置改变一下,或许就Ok了,我们将别人开发的DL ...

  9. golang调用c动态库

    golang调用c动态库 简介 golang调用c语言动态库,动态方式调用,可指定动态库路径,无需系统目录下 核心技术点 封装c动态库 go语言调用c代码 实例代码 封装c动态库 头文件 test_s ...

随机推荐

  1. xcode 设置快捷键 整行上下移动

    设置整行代码上下移动:找到Xcode中的自带的配置文件:/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/ ...

  2. openstack kilo compute更新后报错IncompatibleObjectVersion: Version 1.2 of PciDeviceList is not supported

    前几天在compute节点更新openstack的包后,发现报错IncompatibleObjectVersion: Version 1.2 of PciDeviceList is not suppo ...

  3. python super

    http://hi.baidu.com/thinkinginlamp/item/3095e2f52c642516ce9f32d5 Python中对象方法的定义很怪异,第一个参数一般都命名为self(相 ...

  4. 【MySQL】MySQL忘记root密码解决方案

    转眼间从实习到现在已经快两年了.两年的工作做遇到过很多很多的拦路虎,大部分也通过搜索引擎找到了解决的方案.奈何大脑不是硬盘,偶尔有的问题第二次遇到还是有点抓蒙...所以决定把这些东西记录在博客上.这样 ...

  5. 以前写的关于Linux C/C++的博客

    以前在CU写的关于Linux C/C++的博客 http://blog.chinaunix.net/uid/25909722/cid-24318-list-1.html

  6. 第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息

    第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...

  7. python 解析json loads dumps

    认识 引用模块 重要函数 案例 排序 缩进参数 压缩 参考 认识 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于JavaScript(Standa ...

  8. I2C 总线协议

    1.I2C协议     2条双向串行线,一条数据线SDA,一条时钟线SCL.   SDA传输数据是大端传输,每次传输8bit,即一字节.   支持多主控(multimastering),任何时间点只能 ...

  9. VS2010 调试窗口一闪而过解决方法

    若此时进行的操作是编译(F5),可先运行程序(Ctrl+F5),若仍然一闪而过,用下面方法解决. 方法一: 1.要有头文件cstdlib,在程序最后写一句(return之前)添加:system(&qu ...

  10. android自定义radiobutton样式文字颜色随选中状态而改变

    主要是写一个 color selector 在res/建一个文件夹取名color res/color/color_radiobutton.xml <selector xmlns:android= ...