Dev-C++制作动态库的简单使用
2015-01-27 13:59
225 查看
一、dll的生成方法
1、新建一个dll的工程
2、把生成的dllmain和dll.h删除掉
3、添加自己的头文件和源文件
4、在头文件中加上DLLIMPORT宏
5、在头文件的声明函数里把需要导出的函数加上DLLIMPORT宏和extern "C"
6、在源文件里面把需要导出的函数体也加上DLLIMPORT宏
二、dll的调用方法
1、新建一个控制台程序
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; }
相关文章推荐
- Dev - C++简单使用指南
- Dev-C++ 5.11简单使用说明
- 使用C++制作简单的web服务器(续)
- Linux下C++静态库、动态库的制作与使用
- 使用C++制作简单的web服务器
- C/C++ 编译器和调试器以及静态库、动态库使用汇总
- Dev-C++ 安装&使用教程
- 使用C编译器制作简单二进制文件(i386+)
- C/C++ 编译器和调试器以及静态库、动态库使用汇总
- c++总结系列(一)---动态库dll中使用资源
- XNA Game Studio是一套有着强大功能和简单界面的游戏制作平台,游戏开发商和游戏玩家都可以使用这套工具开发针对Windows XP以及Xbox360的游戏,XNA Game Studio分为两种版本,一种是面向初学者的EXPRESS版本,还有一种是面向专业用户的专业版。用户使用EXPRESS版本开发游戏完全免费,并且可以随意在PC上发行,不过用该工具开发的游戏若是在360上网络发行,就需要交纳99美元的年费。
- C/C++ 编译器和调试器以及静态库、动态库使用汇总
- Linux下,使用C/C++编写一个简单的消息处理程序
- C/C++ 编译器和调试器以及静态库、动态库使用汇总
- Visual C++ Profile的简单使用方法
- throw()使用小结:More effective C++:审慎使用异常规格(转),简单举例
- 使用C++对文件加密的简单例子
- 使用C编译器制作简单二进制文件(i386+)
- Linux下,使用C/C++编写的一个简单的信号处理例程
- [超简单]C++如何使用MySQL数据库