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

一、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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值