Win32 dll编程简单记录

1.函数定义

win32动态链接库的头文件会有下列的定义,每个接口函数定义前都会加上XXX_API

在提供方会预定义XXX_EXPORTS,dllexport和dllimport告诉编译器导出和导入

extern "C" 告诉编译器,函数通过C编译器链接方式来链接,C没有重载和C++链接名字格式不一样

#ifdef XXX_EXPORTS

#define XXX_API extern "C" __declspec(dllexport)

#else

#define XXX_API extern "C" __declspec(dllimport)

#endif

2.函数类型

__stdcall定义了参数堆栈传递方向和堆栈清理者

typedef unsigned int (__stdcall *XXX)(void *data, unsigned int index);

3.多线程

DWORD WINAPI ThreadProc(LPVOID lpParam);

HANDLE thd = CreateThread(NULL, 0, ThreadProc, ¶, 0, NULL);

CloseHandle(thd);

第一个参数表示线程内核对象的安全属性,一般传入NULL表示使用默认设置

第二个参数表示线程栈空间大小,传入0表示使用默认大小(1MB)

第三个参数表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址

第四个参数是传给线程函数的参数

第五个参数指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()

第六个参数将返回线程的ID号,传入NULL表示不需要返回该线程ID号

函数返回值:成功返回新线程的句柄,失败返回NULL

4.信号量

HANDLE semaphore = CreateSemaphore(NULL, 0, 1, NULL);

if(WAIT_TIMEOUT == WaitForSingleObject(semaphore, 2000)){}

在指定的时间内对象被触发,函数返回WAIT_OBJECT_0
超过最长等待时间对象仍未被触发返回WAIT_TIMEOUT
传入参数有错误将返回WAIT_FAILED

CloseHandle(semaphore);

Release(semaphore, 1, NULL);

第一个参数:安全属性,如果为NULL则是默认安全属性
第二个参数:信号量的初始值,要>=0且<=第三个参数
第三个参数:信号量的最大值
第四个参数:信号量的名称
返回值:指向信号量的句柄,如果创建的信号量和已有的信号量重名,那么返回已经存在的信号量句柄

4.socket

/*Client*/
#include
#include
#pragma comment(lib, "ws2_32.lib")

void main()
{
	WSADATA wsaData;
	SOCKET sockClient;
	SOCKADDR_IN addrServer;
	
	if(0 != WSAStartup(MAKEWORD(2,2), &wsaData))
	{
		printf("加载套接字失败!");
		return;
	}
	
	sockClient = socket(AF_INET, SOCK_STREAM, 0);
	if(SOCKET_ERROR == sockClient)
	{
		printf("创建套接字失败!");
		return;
	}
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(6000);
	addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	
	if(INVALID_SOCKET == connect(sockClient, (SOCKADDR*)&addrServer, sizeof(addrServer))
	{
		printf("连接服务器失败!");
		return;
	}
	char message[20] = "hello world!";
	send(sockClient, message, strlen(sessage) + 1, 0);
	closesocket(sockClient);
	WSACleanup();
}
/*Server*/
#include
#include
#pragma comment(lib,"ws2_32.lib")
void main()
{
WSADATA wsaData;
SOCKET sockServer;
SOCKADDR_IN addrServer;
SOCKET sockClient;
SOCKADDR_IN addrClient;
WSAStartup(MAKEWORD(2,2),&wsaData);
sockServer=socket(AF_INET,SOCK_STREAM,0);
addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//INADDR_ANY表示任何IP
addrServer.sin_family=AF_INET;
addrServer.sin_port=htons(6000);//绑定端口6000
bind(sockServer,(SOCKADDR*)&addrServer,sizeof(SOCKADDR));
 
//Listen监听端
listen(sockServer,5);//5为等待连接数目
printf("服务器已启动:\n监听中...\n");
int len=sizeof(SOCKADDR);
char sendBuf[100];//发送至客户端的字符串
char recvBuf[100];//接受客户端返回的字符串
 
//会阻塞进程,直到有客户端连接上来为止
sockClient=accept(sockServer,(SOCKADDR*)&addrClient,&len);
//接收并打印客户端数据
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
 
//关闭socket
closesocket(sockClient);
WSACleanup();
}

5.memcpy

memcpy(void * dst, const void * src, size_t size)

数据拷贝,常用,但是注意如果src或者dst是结构体,要偏移的时候,一定记住先转成(char *),不然就按一个一个结构体偏移了,如果拷贝的数据有重合并且src在前的话,要用memmove,不然后丢失数据

6.读取文件

采用了C语言的标准库函数

char * temp = NULL;
char * value = NULL;
int iValue = 0;
FILE *fp = fopen("xxx", "r");
while(fgets(line, 100, fp) != NULL)
{
    if(line[0] == 'x')
    {
        temp = strtok(line, "x");
        value= strtok(NULL, ",");
        iValue = (int)strtol(value, NULL, 16);
    }
}
fclose(fp);

 

你可能感兴趣的:(C++,C,Window)