C++通过LoadLibrary的方式调用C封装的dll

简介: C++通过LoadLibrary的方式调用C封装的dll

订阅专栏

编写DLL代码

新建工程

新建空项目工程



tt.png

点击确定。然后右键项目选择新建项。

tt.png

再次选择新建项,选中C++文件,将其改为MySocketClient.c,然后选择添加。

tt.png

到这里,新建工程就完成了。

tt.png

然后右键项目,选择属性 将配置类型改为动态库(.dll)

tt.png

编写头文件MySocketClient.h

#ifndef _INC_MYSOCKETCLIENT_H_


#define _INC_MYSOCKETCLIENT_H_


#define Import_SSS


#ifdef Import_SSS


#define API _declspec(dllexport)


#else


#define API _declspec(dllimport)


#endif



#ifdef _cplusplus//extern"C" 来告诉编译器:这是一个用C写成的库文件,请用C的方式来链接它们。


extern "C" {


#endif // _cplusplus


   API//导出函数,让外界调用。


   int socketClient_Init(void **handle);


   API


   int socketClient_Send(void *handle, unsigned char *buf, int buflen);


   API


   int socketClient_Recv(void *handle, unsigned char *buf, int *buflen);


   API


   int socketClient_Destory(void *handle);


#ifdef _cplusplus


}


#endif // _cplusplus


#endif //_INC_MYSOCKETCLIENT_H_


编写MySocketClient.c

#define _CRT_SECURE_NO_WARNINGS


#include <stdlib.h>


#include <string.h>


#include <stdio.h>


#include "MySocketClient.h"


typedef struct _Sck_Handle


{


   char version[16];


   char ip[16];


   int port;


   unsigned char *p;


   int len;


}Sck_Handle;//定义Handle的结构体。


int socketClient_Init(void **handle)


{


   int ret = 0;


   Sck_Handle *tmpHandle = NULL;


   if (handle == NULL)


   {


        ret = -1;


        printf("[socketClient_Init] err %d handle=NULL \n", ret);


        return ret;


   }


   tmpHandle = (Sck_Handle *)malloc(sizeof(Sck_Handle));


   if (tmpHandle == NULL)


   {


        ret = -2;


        printf("[socketClient_Init] err:%d malloc err \n", ret);


   }


   memset(tmpHandle, 0, sizeof(Sck_Handle));//初始化结构体。


   strcpy(tmpHandle->version, "1.0.0.1");


   strcpy(tmpHandle->ip, "192.168.12.121");


   tmpHandle->port = 11111;


   *handle = tmpHandle;


   return ret;


}


socket报文发送


//__declspec(dllexport)


int socketClient_Send(void *handle, unsigned char *buf, int buflen)


{


   int          ret = 0;


   Sck_Handle   *tmpHandle = NULL;


   if (handle == NULL || buf == NULL || buflen <= 0)


   {


        ret = -2;


        printf("func socketclient_send() err :%d  (handle == NULL ||  buf==NULL || buflen <=0 ) \n", ret);


        return ret;


   }


   tmpHandle = (Sck_Handle *)handle;


   tmpHandle->len = buflen;


   tmpHandle->p = (unsigned char *)malloc(buflen);


   if (tmpHandle->p == NULL)


   {


        ret = -2;


        printf("func socketclient_send() err :%d  malloc len:%d \n", ret, buflen);


        return ret;


   }


   memcpy(tmpHandle->p, buf, buflen); //数据的缓存到内存


   printf("接收到发送数据是%s \n", tmpHandle->p);


   return ret;


}


socket报文接受


//__declspec(dllexport)


int socketClient_Recv(void *handle, unsigned char *buf, int *buflen)


{


   int          ret = 0;


   Sck_Handle   *tmpHandle = NULL;


   if (handle == NULL || buf == NULL || buflen == NULL)


   {


        ret = -2;


        printf("func socketclient_recv() err :%d  (handle == NULL ||  buf==NULL || buflen==NULL ) \n", ret);


        return ret;


   }


   tmpHandle = (Sck_Handle *)handle;


   memcpy(buf, tmpHandle->p, tmpHandle->len);


   *buflen = tmpHandle->len; //间接赋值  告诉调用者 收到的数据的长度


   printf("数据长度是%d \n", tmpHandle->len);


   return ret;


}


socket环境释放


//__declspec(dllexport)


int socketClient_Destory(void *handle)


{


   int          ret = 0;


   Sck_Handle   *tmpHandle = NULL;


   if (handle == NULL)


   {


        return -1;


   }


   tmpHandle = (Sck_Handle *)handle;


   if (tmpHandle->p != NULL)


   {


        free(tmpHandle->p); //释放结构体 成员域的 指针所指向的内存空间


   }


   free(tmpHandle); //释放结构体内存


   return 0;


}


然后右键编译工程。在Debug文件夹下面就可以看到生成的dll


调用DLL

新建C++控制台应用程序

tt.png

新建完成后,将编译好的dll文件、lib文件和h文件放到工程下面。

tt.png

右键项目属性,将字符集改为使用多字节字符集


tt.png

下面是调用dll的代码。


#define  _CRT_SECURE_NO_WARNINGS


#include <stdio.h>


#include <windows.h>


#include <iostream>


using namespace std;


//定义指针函数


typedef int(*SOCLETCLIENT_INIT)(void **handle);


typedef int(*SOCKETCLIENT_SEND)(void *handle, unsigned char *buf, int buflen);


typedef int(*SOCKETCLIENT_RECV)(void *handle, unsigned char *buf, int *buflen);


typedef int(*SOCKETCLIENT_DESTORY)(void *handle);


int main()


{


   HINSTANCE hInstance;


   hInstance = LoadLibrary("MySocketClient.dll");


   SOCLETCLIENT_INIT socketClient_Init= (SOCLETCLIENT_INIT)GetProcAddress(hInstance, "socketClient_Init");


   SOCKETCLIENT_SEND socketClient_Send=(SOCKETCLIENT_SEND)GetProcAddress(hInstance, "socketClient_Send");;


   SOCKETCLIENT_RECV socketClient_Recv= (SOCKETCLIENT_RECV)GetProcAddress(hInstance, "socketClient_Recv");;


   SOCKETCLIENT_DESTORY socketClient_Destory= (SOCKETCLIENT_DESTORY)GetProcAddress(hInstance, "socketClient_Destory");;


   unsigned char buf[1024];


   int buflen;


   unsigned char out[1024];


   int outlen;


   void *handle = NULL;


   int ret = 0;


   strcpy((char *)buf, "aaaaAAAAAFFffffffdddddddd");


   buflen = 9;


   //客户端初始化 获取handle上下


   ret = socketClient_Init(&handle /*out*/);


   if (ret != 0)


   {


        printf("func socketclient_init() err:%d \n ", ret);


        goto End;


   }


   //客户端发报文


   ret = socketClient_Send(handle /*in*/, buf /*in*/, buflen /*in*/);


   if (ret != 0)


   {


        printf("func socketclient_send() err:%d \n ", ret);


        goto End;


   }


   //客户端收报文


   ret = socketClient_Recv(handle /*in*/, out /*in*/, &outlen/*in out*/);


   if (ret != 0)


   {


        printf("func socketclient_recv() err:%d \n ", ret);


        goto End;


   }


   printf("接收到的数据长度是%d \n",outlen);


End:


   //客户端释放资源


   ret = socketClient_Destory(handle/*in*/);


if (hInstance != NULL)


   {


        FreeLibrary(hInstance);


        hInstance = NULL;


   }


   printf("hello...\n");


   system("pause");


   return 0;


}


代码链接:https://download.csdn.net/download/hhhhhhhhhhwwwwwwwwww/12831335





tt.png

目录
相关文章
|
6月前
|
C++
C++中的封装、继承与多态:深入理解与应用
C++中的封装、继承与多态:深入理解与应用
149 1
|
5月前
|
缓存 网络协议 Linux
c++实战篇(三) ——对socket通讯服务端与客户端的封装
c++实战篇(三) ——对socket通讯服务端与客户端的封装
118 0
|
2月前
|
数据安全/隐私保护 C语言 C++
C++(七)封装
本文档详细介绍了C++封装的概念及其应用。封装通过权限控制对外提供接口并隐藏内部数据,增强代码的安全性和可维护性。文档首先解释了`class`中的权限修饰符(`public`、`private`、`protected`)的作用,并通过示例展示了如何使用封装实现栈结构。接着介绍了构造器和析构器的使用方法,包括初始化列表的引入以及它们在内存管理和对象生命周期中的重要性。最后,通过分文件编程的方式展示了如何将类定义和实现分离,提高代码的模块化和复用性。
|
3月前
|
存储 C++
C++ dll 传 string 类 问题
C++ dll 传 string 类 问题
26 0
|
4月前
|
C++ 容器
【C++】map和set封装
【C++】map和set封装
38 2
|
4月前
|
存储 开发框架 Java
|
5月前
|
存储 Java C#
C++语言模板类对原生指针的封装与模拟
C++|智能指针的智能性和指针性:模板类对原生指针的封装与模拟
|
5月前
|
数据安全/隐私保护 C++
C++语言深入理解类的封装与数据隐藏
深入理解类的封装与数据隐藏
|
4月前
|
存储 C++ 容器
【C++】开散列实现unordered_map与unordered_set的封装
【C++】开散列实现unordered_map与unordered_set的封装
52 0
|
6月前
|
存储 C语言 C++
从C语言到C++_31(unordered_set和unordered_map介绍+哈希桶封装)(上)
从C语言到C++_31(unordered_set和unordered_map介绍+哈希桶封装)
56 3