您的位置:首页 > 编程语言 > C语言/C++

Dev-C++制作动态库的简单使用

2015-01-27 13:59 225 查看
一、dll的生成方法

1、新建一个dll的工程

2、把生成的dllmain和dll.h删除掉

3、添加自己的头文件和源文件

4、在头文件中加上DLLIMPORT宏

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */


5、在头文件的声明函数里把需要导出的函数加上DLLIMPORT宏和extern "C"

extern "C" DLLIMPORT int CreateGetPictureMainThread();
extern "C" DLLIMPORT int GetPictureData(char *OutData, int *valid_size, int no);


6、在源文件里面把需要导出的函数体也加上DLLIMPORT宏

#ifndef _GET_PICTURE_H_
#define _GET_PICTURE_H_

#if BUILDING_DLL # define DLLIMPORT __declspec (dllexport) #else /* Not BUILDING_DLL */ # define DLLIMPORT __declspec (dllimport) #endif /* Not BUILDING_DLL */

#include <cstdio>
#include <windows.h>
#include <cstring>
#include <Winsock2.h>
#include <pthread.h>
#include <sys/types.h>

#define SERVER_PORT 8187
#define BUFFER_SIZE 1024
#define MAX_PICTURE_SIZE (400*1024)
#define MAX_CACHE_PICTURE 5
#define MAX_FILE_NUM 50
#define COMMAND_SIZE 10

typedef struct PICTURE_INFO
{
unsigned int picture_valid_size;
char picture_data[MAX_PICTURE_SIZE];
}PictureInfo;

extern PictureInfo picture_info[MAX_CACHE_PICTURE];
extern char cmd[COMMAND_SIZE];

int Connect_server(char *ip, SOCKET *sockClient);
int SendRequest(int sockfd);
int SendFinishAck(int sockfd);
int GetTimeArg(int sockfd);
int RecvPicture(PictureInfo *pInfo, int sockfd);
int WritePictureToFile(PictureInfo *pInfo, char *file_name);
int GetIPFromConfigFile(char *ip);
int SetFileName(char *file_name);
void *GetPictureMainThread(void *arg);

extern "C" DLLIMPORT int CreateGetPictureMainThread(); extern "C" DLLIMPORT int GetPictureData(char *OutData, int *valid_size, int no);

#endif


#include "GetPictureThread.h"

PictureInfo picture_info[MAX_CACHE_PICTURE];
char cmd[COMMAND_SIZE];

void *GetPictureMainThread(void *arg)
{
SOCKET sockClient;
char ip[16];
char file_name[20];
int nbytes;
static int index = 0;

memset(ip, 0, 16);
memset(file_name, 0, sizeof(file_name));
GetIPFromConfigFile(ip);
Connect_server(ip, &sockClient);

while(1)
{
nbytes = SendRequest(sockClient);
if (nbytes == 0 || nbytes == -1)
{
printf("The server has been closed.Try to reconnect the server...\n");
closesocket(sockClient);
WSACleanup();
Connect_server(ip, &sockClient);
Sleep(1000);
}else
{
memset(cmd, 0, COMMAND_SIZE);
recv(sockClient, cmd, COMMAND_SIZE, 0);
if (strcmp(cmd, "NOT_READY") == 0)
{
Sleep(10);
continue;
}else if (strcmp(cmd, "READY") == 0)
{
printf("cmd: %s, index: %d\n", cmd, index);
RecvPicture(&picture_info[index], sockClient);
SendFinishAck(sockClient);
GetTimeArg(sockClient);
//memcpy(file_name, "picture.jpg", sizeof(file_name));
SetFileName(file_name);
WritePictureToFile(&picture_info[index], file_name);
index++;
if (index == MAX_CACHE_PICTURE)
{
index = 0;
}
}
}
}

closesocket(sockClient);
WSACleanup();
}

DLLIMPORT int CreateGetPictureMainThread()
{
pthread_t pid;

if (pthread_create(&pid, NULL, GetPictureMainThread, NULL) == -1)
{
printf("pthread_create failed.\n");
exit(1);
}

return 0;
}

int SetFileName(char *file_name)
{
static int count = 1;
char suffix[] = ".jpg";

memset(file_name, 0, sizeof(file_name));
sprintf(file_name, "%d%s", count, suffix);
count++;
if (count > MAX_FILE_NUM)
{
count = 1;
}

return 0;
}

int Connect_server(char *ip, SOCKET *sockClient)
{
int err;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return -1;
}

if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return -1;
}

*sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr(ip);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(SERVER_PORT);
err = connect(*sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
if (err == 0)
{
printf("Connected successfully.\nWait to receive picture...\n");
}else
{
printf("Connect failed.\n");
}
return 0;
}

int SendRequest(int sockfd)
{
memset(cmd, 0, COMMAND_SIZE);
memcpy(cmd, "REQUEST", COMMAND_SIZE);
int length = send(sockfd, cmd, COMMAND_SIZE, 0);
if (length == -1)
{
printf("send failed.\n");
}
return length;
}

int SendFinishAck(int sockfd)
{
memset(cmd, 0, COMMAND_SIZE);
memcpy(cmd, "RECV_OK", COMMAND_SIZE);
int length = send(sockfd, cmd, COMMAND_SIZE, 0);
if (length == -1)
{
printf("send failed.\n");
}
return length;
}

int GetTimeArg(int sockfd)
{
long int time;
recv(sockfd, (char*)&time, 4, 0);
printf("Internet transfer time: %ld ms\n", time);

recv(sockfd, (char*)&time, 4, 0);
printf("Capture picture whole time: %ld ms\n", time);

return 0;
}

int RecvPicture(PictureInfo *pInfo, int sockfd)
{
unsigned int recvsize = 0;
unsigned int length = 0;
char buffer[BUFFER_SIZE];
char *Addr = pInfo->picture_data;

memset(pInfo, 0, sizeof(PictureInfo));
memset(buffer, 0, BUFFER_SIZE);

recv(sockfd, (char*)&pInfo->picture_valid_size, 4, 0);
printf("size: %d\n", pInfo->picture_valid_size);
while(recvsize != pInfo->picture_valid_size)
{
length = recv(sockfd, buffer, BUFFER_SIZE, 0);

if (length < 0)
{
printf("Recieve Data From Server Failed!\n");
break;
}
memcpy(Addr, buffer, length);
recvsize += length;
Addr += length;
memset(buffer, 0, BUFFER_SIZE);
}

return 0;
}

int WritePictureToFile(PictureInfo *pInfo, char *file_name)
{
unsigned int write_length = 0;
unsigned int length;
char *Addr = pInfo->picture_data;
FILE *pFile = fopen(file_name, "wb");

length = fwrite(Addr, sizeof(char), pInfo->picture_valid_size, pFile);
if (length == pInfo->picture_valid_size)
{
printf("Write File[%s] Finished[%dbytes]!\n", file_name, length);
}else
{
printf("Write failed.\n");
}

fclose(pFile);
return 0;
}

int GetIPFromConfigFile(char *ip)
{
char str[8];
char temp[24];
int n = 0;

FILE *pconf = fopen("config.txt", "r+");
if (pconf == NULL)
{
printf("Open file[config.txt] failed.\n");
exit(1);
}
memset(temp, 0, 24);
n = fread(temp, sizeof(temp), 1, pconf);
memset(str, 0, 8);
memcpy(str, temp, 8);
memcpy(ip, temp+8, 16);
printf("%s\n", temp);

fclose(pconf);
return 0;
}

DLLIMPORT int GetPictureData(char *OutData, int *valid_size, int no)
{
if (OutData == NULL)
{
*valid_size = picture_info[no].picture_valid_size;
}else
{
*valid_size = picture_info[no].picture_valid_size;
//OutData = picture_info[no].picture_data;
memset(OutData, 0, sizeof(OutData));
memcpy(OutData, picture_info[no].picture_data, picture_info[no].picture_valid_size);
}

return 0;
}


二、dll的调用方法
1、新建一个控制台程序

#include <iostream>
#include <cstdio>
#include <windows.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[]) {

int size;

typedef int (*FUNT)(void);
typedef int (*GETPICTURE)(char *, int *, int);

HINSTANCE Hint = LoadLibrary("GetPictureThread.dll");//load dll path
FUNT CreateGetPictureMainThread = (FUNT)GetProcAddress(Hint, "CreateGetPictureMainThread");//get function handle
GETPICTURE GetPictureData = (GETPICTURE)GetProcAddress(Hint, "GetPictureData");

if (CreateGetPictureMainThread == NULL)
{
printf("load dll failed.\n");
exit(1);
}

CreateGetPictureMainThread();
getchar();
GetPictureData(0, &size, 0);
char pData[size];
GetPictureData(pData, &size, 0);
printf("size: %d\n", size);

FILE *pFile = fopen("mypicture.jpg", "wb");
if (pFile == NULL)
{
printf("open failed.\n");
exit(1);
}
fwrite(pData, 1, size, pFile);

fclose(pFile);

getchar();
FreeLibrary(Hint);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐