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);