标签 C语言 下的文章

WaitForSingleObject

 


DWORD WaitForSingleObject(

  HANDLE hHandle,

  DWORD dwMilliseconds

);

参数hHandle是一个事件的句柄,第二个参数dwMilliseconds是时间间隔。如果时间是有信号状态返回WAIT_OBJECT_0,如果时间超过dwMilliseconds值但时间事件还是无信号状态则返回WAIT_TIMEOUT。

hHandle可以是下列对象的句柄:

Change notification 

Console input 

Event 

Job 

Memory resource notification 

Mutex 

Process 

Semaphore 

Thread 

Waitable timer

WaitForSingleObject函数用来检测hHandle事件的信号状态,当函数的执行时间超过dwMilliseconds就返回,但如果参数dwMilliseconds为INFINITE时函数将直到相应时间事件变成有信号状态才返回,否则就一直等待下去,直到WaitForSingleObject有返回直才执行后面的代码。在这里举个例子:

先创建一个全局Event对象g_event:

    CEvent g_event;

在程序中可以通过调用CEvent::SetEvent设置事件为有信号状态。

下面是一个线程函数MyThreadPro()

UINT CFlushDlg::MyThreadProc( LPVOID pParam )

{

     WaitForSingleObject(g_event,INFINITE);

     For(;;)

        {

         ………….

        }

     return 0;

}

在这个线程函数中只有设置g_event为有信号状态时才执行下面的for循环,因为g_event是全局变量,所以我们可以在别的线程中通过g_event. SetEvent控制这个线程。

还有一种用法就是我们可以通过WaitForSingleObject函数来间隔的执行一个线程函数的函数体

     UINT CFlushDlg::MyThreadProc( LPVOID pParam )

{

     while(WaitForSingleObject(g_event,MT_INTERVAL)!=WAIT_OBJECT_0)

     {

         ………………

     }

     return 0;

}

在这个线程函数中可以可以通过设置MT_INTERVAL来控制这个线程的函数体多久执行一次,当事件为无信号状态时函数体隔MT_INTERVAL执行一次,当设置事件为有信号状态时,线程就执行完毕了。

 

windows平台cl.exe编译pcre 8.33

最近在windows平台开发的一个project需要使用正则表达式,当然自己实现一个regexp也是可以的,只是太蛋疼且技术不到家。所以我优先考虑了open source的library,pcre是比较有名的库,在linux编译都是普通的套路,不过在win下面就稍微麻烦一点了。

编译的方法主要参考源代码zip包里面的NON-AUTOTOOLS-BUILD文件。

  1. 下载最新的pcre:ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.33.zip (zip/tar.gz/tar.bz2三种格式任选一种,windows的一般用zip),并解压。
  2. 重命名config.h.generic为config.h,这是generic配置文件,需要根据具体的环境对预编译做相应修改。
    HAVE_BCOPY 1改为0,HAVE_INTTYPES_H 1改为0,HAVE_STDINT_H 1改为0。
    如果不修改,在下面编译dftables的步骤中会报错:  



    pcre_internal.h(198) : fatal error C1083: Cannot open include file: 'inttypes.h': No such file or directory

  3. 重命名pcre.h.generic为pcre.h,重命名pcre_chartables.c.dist为pcre_chartables.c

  4. cl -MD -DHAVE_CONFIG_H dftables.c生成dftables.exe

  5. dftables.exe pcre_chartables.c (修改了一些注释,不知道目的何在)

  6. cl -O1 -MD -DHAVE_CONFIG_H -c pcre_chartables.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_compile.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_config.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_dfa_exec.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_exec.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_fullinfo.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_get.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_globals.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_info.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_maketables.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_newline.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_ord2utf8.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_refcount.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_study.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_tables.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_try_flipped.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_ucd.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_valid_utf8.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_version.c

cl -O1 -MD -DHAVE_CONFIG_H -c pcre_xclass.c

lib -out:pcre.lib pcre_chartables.obj pcre_compile.obj pcre_config.obj pcre_dfa_exec.obj pcre_exec.obj pcre_fullinfo.obj pcre_get.obj pcre_globals.obj pcre_info.obj pcre_maketables.obj pcre_newline.obj pcre_ord2utf8.obj pcre_refcount.obj pcre_study.obj pcre_tables.obj pcre_try_flipped.obj pcre_ucd.obj pcre_valid_utf8.obj pcre_version.obj pcre_xclass.obj

最后生成的pcre.lib就是我们所需要的pcre库文件。

【注意】,如果要编译debug版本的pcre.lib,请用-MDd替代-MD,否则项目会出现“MSVCRTD.lib(cinitexe.obj) : warning LNK4098: 默认库“msvcrt.lib”的问题。

拷贝pcre.h和pcre.lib到我们自己项目的目录,然后在源代码顶部加入以下代码:

#include "pcre.h" 
#pragma comment(lib,"pcre.lib")

用以下代码测试:

version= pcre_version(); 

wchar_t *shit = (wchar_t *)malloc(strlen(version));

MultiByteToWideChar(CP_ACP,0,version,-1,shit,wcslen(shit));

MessageBox(hWnd,shit,shit,MB_OK);

USBAutoCopy:USB存储设备文件自动复制

在公司上班的同事工作有一部分是拷贝终端里面SD卡的日志,日志(文本文件)存在于不同的目录,以前每次电脑插上SD卡之后进入不同的目录ctrl+C然后再ctrl+V,而且每个终端的日志都要根据终端唯一ID号分别放在单独的目录。工作十分繁琐耗时,当我写完这个UsbAutoCopy之后,才发现以前的拷贝方式简直是弱爆了。下面图中的【D: est105285】105285就是终端唯一ID号。

USBAutoCopy:USB存储设备文件自动复制

用法

运行程序,在【文件列表】文本框里面填写需要在移动存储设备中拷贝的文件列表,每个文件一行,必须要“"开头。不要有留空行,【复制到目录中】设置拷贝目标文件夹,必须是一个已经存在的目录,并且不能为空。移动存储设备(U盘、SD卡....)插入后程序自动识别盘符并开始复制文件。并在【日志】中显示复制文件的结果是成功还是失败,以及失败原因。

下载

因为这个程序针对公司内部,对其他人来说没有任何实用价值,给出二进制和源码仅供交流参考。

实用visual studio 2010开发,二进制zip里面已经加入vc++ 2010 runtime(msvcr100.dll),某些系统如果无法运行,请下载Microsoft Visual C++ 2010 可再发行组件包 (x86)

源码:UsbAutoCopy.V1.0.Src

二进制:UsbAutoCopy.V1.0.Bin

linux简单tcp通讯

server

#include <sys/socket.h>
#include <stdio.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/types.h>

#define portnum 3456

int main(int argc,char *argv[])
{
int s_fd,c_fd;
char buffer[1024];
struct sockaddr_in server_addr;//服务器ip地址
struct sockaddr_in client_addr;//客户端ip地址
int nbytes;
int cli_size;
/*
struct sockaddr_in
{
short int sin_family; //ip地址族
unsigned short int sin_port; //端口号
struct in_addr sin_addr; //ip地址
unsigned char sin_zero[8]; //填0
}
*/
/*
struct in_addr
{
unsigned long s_addr;
}
*/
s_fd=socket(AF_INET,SOCK_STREAM,0);
//地址描述,套接口类型,套接口所用的协议
if(s_fd==-1)
{
fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
exit(1);
}
printf("socket() return value:%d\n",s_fd);

//服务器填充sockaddr结构
bzero(&server_addr,sizeof(struct sockaddr_in));//初始化,置0
server_addr.sin_family=AF_INET; //Internet
//(将本机器上的long数据转化为网络上的long数据)和任何主机通信
//INADDR_ANY表示额可以接收任意IP地址的数据
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(portnum);
bzero(&(server_addr.sin_zero),8);
int b;
b=bind(s_fd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr));
//未捆绑套接口的描述字,赋予套接口的地址,地址的长度
if(b==-1)
{
fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
exit(1);
}
printf("bind() return value:%d\n",b);

//设置允许连接的最大客户端数
int c;
c=listen(s_fd,5);//最大监听数是5
if(c==-1)
{
fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
exit(1);
}
printf("listen() return value:%d\n",c);

//TCP循环服务器
while(1)
{
cli_size=sizeof(struct sockaddr_in); //获取ip地址结构的大小
if((c_fd=accept(s_fd,(struct sockaddr *)&client_addr,&cli_size))==-1)
{
fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
exit(1);
}
//套接口的描述字,客户端的ip地址,地址长度
printf("accept() return value:%d\n",c_fd);

//将网络地址转换成可读的ip地址
fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr));

//接收从客户端发送来的数据,返回读取的字节数
//if(!fork())
//{
if((nbytes=read(c_fd,buffer,1024))==-1)
{
fprintf(stderr,"Read Error:%s\n",strerror(errno));
exit(1);
}
buffer[nbytes]='\0'; //给数据结束标志
//输出从客户端读取的数据
printf("Server received %s\n",buffer);
//process();
close(c_fd);
exit(0);
//}
}
// close(c_fd);//关闭客户端的文件描述符
// close(s_fd);
close(s_fd);
exit(0);
}

client

#include "stdio.h"
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#define portnum 3456

int main(int argc,char *argv[])
{
struct sockaddr_in server_addr;
int c_fd;
char buffer[1024];
struct hostent *host;

if(argc != 2)
{
fprintf(stderr,"Gethostname error\n");
exit(1);
}

if((host=gethostbyname(argv[1])) == NULL)
{
fprintf(stderr,"Gethostname error\n");
exit(1);
}

c_fd=socket(AF_INET,SOCK_STREAM,0);
if(c_fd == -1)
{
fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));
}
printf("socket() return value:%d\n",c_fd);

//客户端sockaddr结构
bzero(&server_addr,sizeof(struct sockaddr_in));//初始化,置0
server_addr.sin_family=AF_INET; //Internet
server_addr.sin_port=htons(portnum);
//server_addr.sin_addr=*((struct in_addr *)host.h_addr);//指向主机的第一个ip地址
int a;
a=connect(c_fd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr_in));
if(a==-1)
{
fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
exit(1);
}
printf("connect() return value:%d\n",a);
//从标准输入获取buffer大小的数据放入buffer中
fgets(buffer,sizeof(buffer),stdin);
write(c_fd,buffer,sizeof(buffer));//向服务器写数据
close(c_fd);
return 0;
}