zoukankan      html  css  js  c++  java
  • C语言 动态库简单开发

    动态库项目

    //简单的动态库开发----报文发送
    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    //定义上下文结构体
    typedef struct _SCK_HANDLE{
        //定义报文IP
        char ipaddress[30];
        //定义报文端口
        char port[10];
        //定义报文接受数组
        unsigned char * buf;
        //定义报文长度
        int buflen;
    }SCK_HANDLE;
    
    
    //初始化上下文
    _declspec(dllexport)
    int cltSocketInit(void **handle/*out*/){
        int ERRO_MSG = 0;
        if (handle == NULL)
        {
            ERRO_MSG = 1;
            printf("handle==NULL 报文初始化失败 erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        //定义上下文指针
        SCK_HANDLE *shandle = NULL;
        //分配内存
        //详述:此处分配内存必须分配堆内存(malloc函数分配),这也正是malloc函数真正的用途所在
        //此处不可以分配栈内存,栈内存会被系统自动回收,但是报文的发送与接受所使用的上下文SCK_HANDLE,必须长时间存在
        //何时回收必须由用户决定,而不能随便的被回收
        //同样使用静态区也不合适,因为无法人为回收内存空间,必须等待电脑关机,综上所述,只能使用malloc函数分配内存
        shandle = (SCK_HANDLE *)malloc(sizeof(SCK_HANDLE));
        //重置内存空间
        memset(shandle, 0, sizeof(SCK_HANDLE));
        strcpy(shandle->ipaddress, "192.168.0.128");
        strcpy(shandle->port, "88");
        *handle = shandle;
        return ERRO_MSG;
    }
    //客户端发报文
    _declspec(dllexport)
    int cltSocketSend(void *handle/*in*/, unsigned char *buf/*in*/, int buflen/*in*/){
        int ERRO_MSG = 0;
        if (handle == NULL)
        {
            ERRO_MSG = 1;
            printf("handle==NULL handle不可以为NULL erro msg :%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        if (buf == NULL)
        {
            ERRO_MSG = 2;
            printf("buf==NULL buf不可以为NULL erro msg :%d
    ", 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 = 3;
            printf("sh->buf==NULL 内存分配失败 erro msg :%d
    ", 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 = 0;
        if (handle == NULL || buf == NULL || buflen == NULL)
        {
            ERRO_MSG = 1;
            printf("handle == NULL || buf == NULL || buflen==NULL erro msg:%d
    ", 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 = 0;
        return ERRO_MSG;
    }
    //客户端释放资源
    _declspec(dllexport)
    int cltSocketDestory(void **handle){
        int ERRO_MSG = 0;
        if (handle == NULL)
        {
            ERRO_MSG = 1;
            printf("handle==NULL%d
    ", 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 = 0;
        }
        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 = 0;
        //初始化报文
        void *handle = NULL;
        ret = cltSocketInit(&handle);
        if (ret==0)
        {
            printf("报文初始化成功!
    ");
        }
        //发送报文
        unsigned char *str = "1234567890qwertyuiop";
        int buflen = 10;
        ret = cltSocketSend(handle, str, buflen);
        if (ret == 0)
        {
            printf("报文发送成功!
    ");
        }
        unsigned char *str2 = NULL;
        int buflen2 = 0;
        //接受报文
        ret = cltSocketRev(handle, &str2, &buflen2);
        if (ret == 0)
        {
            unsigned char *buf3 = (char *)malloc(sizeof(char)*12);
            memset(buf3,0,sizeof(char)*12);
            memcpy(buf3, str2, 10);
            //strcpy(buf3, str2);
            printf("报文接受成功!
    ");
            printf("接受报文:%s;报文长度是%d
    ", buf3, buflen2);
        }
        //释放上下文
        cltSocketDestory(&handle);
        printf("%p
    ", handle);
        system("pause");
    }

    效果图

  • 相关阅读:
    后缀数组板子
    上海高校金马五校赛 J
    西安电子科技大学第16届程序设计竞赛网络同步赛 G-小国的复仇
    HDU
    string 与char* char[]之间的转换 .
    (分治思想)(归并排序)C
    如何取出 Map中key和value的值
    C++ STL 中 map 容器的说明和使用技巧 .
    (经典map)A
    Babelfish(6.1.2)(sort结构体排序)(sscanf()基本使用方法)(二分法)
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5512909.html
Copyright © 2011-2022 走看看