图解VC++6.0和ACE 5.4 开发入门

一 工具和下载

工具和环境:

Win7, VC++6, ACE5.4

可在Win7下运行的VC6下载:

http://blog.csdn.net/bcbobo21cn/article/details/44200205

ACE安装包和本文demo代码下载:

http://pan.baidu.com/s/1kUUOOlh

注意有两个ace安装包,5.4是dsw的工程,6.3是sln的工程

二 安装环境

下载ace54,解压;

在vc6.0中打开ace源码;

2个工程;网上资料有说3个工程;

在工程中双击config.h,询问是否要创建,单击是;

输入

#include "ace/config-win32.h"

看下lib目录,现在是空的;

在工程设置中作如下设置,

开始build;一堆cpp文件一个个被编译;

编译成功;

但是查看lib目录,空的;啥也没有;

生成了dll, 不在lib目录,并且没有生成lib文件;

重新修改工程设置如下图;

要改两处;

..\lib\aced.dll

/out:"..\lib\aced.dll" /implib:"..\lib\aced.lib"

这个和网上别的教程有所区别;大家可以参考之;

再bulid,好了,dll和lib都出来了;此框架就一个dll;

三 控制台demo

新建控制台工程;

新建一个空工程;

添加cpp源文件;

代码见后;

再新建客户端工程;前面那个是服务器端项目;

预处理器和附加包含路径;如下图;加入这个;

ACE_AS_STATIC_LIBS

添加lib库和附加库路径;

服务器端和客户端的代码;

#include "ace/Addr.cpp"

#include "ace/Time_Value.cpp"

#include "ace/Message_Queue.h"

#include "ace/Asynch_IO.h"

#include "ace/OS.h"

#include "ace/Proactor.h"

#include "ace/Asynch_Acceptor.h"

#include "ace/SOCK_SEQPACK_Association.h"

class Proactive_Service : public ACE_Service_Handler

{

public:

~Proactive_Service ()

{

if (this->handle () != ACE_INVALID_HANDLE)

ACE_OS::closesocket (this->handle ());

}

/******************************************************/

/*每当客户端连接到服务器就会调用此函数                 */

/******************************************************/

virtual void open (ACE_HANDLE h, ACE_Message_Block&)

{

this->handle (h);

//打开与客户端的读取流

if (this->reader_.open (*this) != 0 )

{

delete this;

return;

}

//开打与客户端的写出流

if (this->writer_.open (*this) != 0 )

{

delete this;

return;

}

ACE_Message_Block *mb = new ACE_Message_Block(buffer,1024);

if (this->reader_.read (*mb, mb->space ()) != 0)

{

ACE_OS::printf("Begin read fail/n");

delete this;

return;

}

return;

}

//异步读完成后会调用此函数

virtual void handle_read_stream

(const ACE_Asynch_Read_Stream::Result &result){

ACE_Message_Block &mb = result.message_block ();

//如果读取失败说明客户端关闭,在这里删除客户端连接资源

if (!result.success () || result.bytes_transferred () == 0)

{

mb.release ();

delete this;

return;

}

mb.copy("");    //为字符串添加结束标记‘/0‘

ACE_OS::printf("rev:/t%s/n",mb.rd_ptr());

mb.release();

ACE_Message_Block *mbb = new ACE_Message_Block(100);

mbb->copy("daye say hello");

if (this->writer_.write(*mbb,mbb->length()) !=0)

{

delete this;

return;

}

ACE_Message_Block *nmb = new ACE_Message_Block(buffer,1024);

if (this->reader_.read (*nmb, nmb->space ()) != 0)

return;

}

//异步写完成后会调用此函数

virtual void handle_write_dgram

(const ACE_Asynch_Write_Stream::Result &result)

{

ACE_Message_Block &mb = result.message_block ();

mb.release();

return;

}

private:

ACE_Asynch_Read_Stream reader_;

ACE_Asynch_Write_Stream writer_;

char buffer[1024];

};

int main(int argc, char *argv[])

{

ACE::init();//初始化dll资源

int port=20002;//指定监听端口

ACE_Asynch_Acceptor<Proactive_Service> acceptor;

//在指定的端口上进行监听

if (acceptor.open (ACE_INET_Addr (port)) == -1)

return -1;

//开始等待客户端的连接

ACE_Proactor::instance ()->proactor_run_event_loop();

ACE::fini();//释放dll资源

return 0;

}

========

#include "ace/SOCK_Connector.h"

#include "ace/OS_NS_string.h"

#include "ace/OS_NS_stdio.h"

#include "ace/Addr.cpp"

#include "ace/Time_Value.cpp"

#include "ace/Message_Queue.h"

#include "ace/Asynch_IO.h"

#include "ace/OS.h"

#include "ace/Proactor.h"

#include "ace/Asynch_Connector.h"

class Proactive_Client : public ACE_Service_Handler

{

public:

~Proactive_Client ()

{

if (this->handle () != ACE_INVALID_HANDLE)

ACE_OS::closesocket (this->handle ());

}

virtual void open (ACE_HANDLE h, ACE_Message_Block&)

{

this->handle (h);

if (this->reader_.open (*this) != 0 )

{

delete this;

return;

}

if (this->writer_.open (*this) != 0 )

{

delete this;

return;

}

ACE_Message_Block *mb = new ACE_Message_Block(buffer,1024);

if (this->reader_.read (*mb, mb->space ()) != 0)

{

delete this;

return;

}

ACE_OS::printf("connceted/n");

time_t now = ACE_OS::gettimeofday().sec();

char *time = ctime(&now);        //获取当前时间的字符串格式

ACE_Message_Block *mbb = new ACE_Message_Block(100);

mbb->copy(time);

if (this->writer_.write(*mbb,mbb->length()) !=0)

{

delete this;

return;

}

return;

}

//异步读完成后会调用此函数

virtual void handle_read_stream

(const ACE_Asynch_Read_Stream::Result &result)

{

ACE_Message_Block &mb = result.message_block ();

if (!result.success () || result.bytes_transferred () == 0)

{

mb.release ();

delete this;

return;

}

mb.copy("");    //为字符串添加结束标记‘/0‘

ACE_OS::printf("rev:/t%s/n",mb.rd_ptr());

mb.release();

ACE_Message_Block *nmb = new ACE_Message_Block(buffer,1024);

if (this->reader_.read (*nmb, nmb->space ()) != 0)

return;

}

//异步写完成后会调用此函数

virtual void handle_write_dgram

(const ACE_Asynch_Write_Stream::Result &result)

{

ACE_Message_Block &mb = result.message_block ();

mb.release();

return;

}

private:

ACE_Asynch_Write_Stream writer_;

ACE_Asynch_Read_Stream reader_;

char buffer[1024];

};

int main(int argc, char *argv[])

{

ACE::init();

ACE_INET_Addr addr(20002,"127.0.0.1");//服务器地址和端口

ACE_Asynch_Connector<Proactive_Client> connector;

connector.open();

if (connector.connect(addr) == -1)

return -1;

ACE_Proactor::instance()->proactor_run_event_loop();

ACE::fini();

return 0;

}

运行下;

找不到dll,把前面生成的aced.dll直接拷贝到此工程生成的exe文件的同一目录下;再运行;看到客户端和服务器端通信了;不过此代码只能通信一次;一锤子而已;

要搞成项目需要自己搞定;

四 窗口模式的通信

新建一个MFC客户端;

做一个如下的界面;

在项目中加入四个文件;

========

RecvTask.h

#ifndef RECVTASK_H

#define RECVTASK_H

#include "ace/Task.h"

#include "ace/OS.h"

#include "ace/INET_Addr.h"

#include "ace/SOCK_Connector.h"

#define MSG_LEN_BYTES 128

#define TIME_OUT_VALUE 1000000

class RecvTask: public ACE_Task<ACE_MT_SYNCH>

{

public:

RecvTask();

int open(void* p);

int close(u_long);

//接收服务器的信息

int svc(void);

};

#endif

RecvTask.cpp

#include "stdafx.h"

#include "RecvTask.h"

#include "ace/ACE.h"

#include "ace/OS.h"

#include "ace/SOCK_Connector.h"

#include "ace/INET_Addr.h"

#include "ace/Task.h"

#include "Client.h"

int RecvTask::svc(void)

{

while(true)

{

Client::getInstance()->recvMessage();

ACE_OS::sleep(ACE_Time_Value( 0, 5000 ));

}

}

int RecvTask::open(void* p)

{

activate();

return 0;

}

int RecvTask::close(u_long)

{

return 0;

}

RecvTask::RecvTask(){}

Client.h

#ifndef CLIENR_H

#define CLIENR_H

#include "stdafx.h"

#include "ace/ACE.h"

#include "ace/OS.h"

#include "ace/SOCK_Connector.h"

#include "ace/INET_Addr.h"

#include "ace/Task.h"

#include "RecvTask.h"

class Client

{

public:

~Client();

/***************************************************************/

/* 根据ip地址和端口号,连接服务器,如果连接成功返回0,失败返回-1 */

/***************************************************************/

int connect(int port,char * localhost);

/***************************************************************/

/* 获取客户端实例                                              */

/***************************************************************/

static Client * getInstance();

/***************************************************************/

/* 给服务器发送数据信息,返回发的字节数                        */

/***************************************************************/

int sendMessage(char * msg);

/**************************************************************/

/* 关闭与远程服务器的连接,成功返回0,失败返回-1              */

/**************************************************************/

int close();

void recvMessage();

private:

Client();

ACE_SOCK_Connector connector;

ACE_Thread_Mutex mutex;

RecvTask * recvTask;

static Client * instance;

static BOOL hasInstance;

ACE_SOCK_Stream stream;

};

#endif

Client.cpp

#include "stdafx.h"

#include "RecvTask.h"

#include "ace/ACE.h"

#include "ace/OS.h"

#include "ace/SOCK_Connector.h"

#include "ace/INET_Addr.h"

#include "ace/Task.h"

#include "Client.h"

#include "ace/OS_NS_string.h"

Client * Client::instance=NULL;

BOOL Client::hasInstance=false;

Client::~Client()

{

if (recvTask!=NULL)

{

delete recvTask;

recvTask=NULL;

}

}

Client * Client::getInstance()

{

if (!hasInstance)

{

instance= new Client();

hasInstance=true;

}

return instance;

}

int Client::connect(int port,char * localhost)

{

recvTask = new RecvTask();

//stream = new ACE_SOCK_Stream();

ACE_INET_Addr  remote_addr(port,localhost);

int result=connector.connect(stream, remote_addr);

if (result==0)

{

recvTask->open(0);

}else{

recvTask->close(0);

delete recvTask;

}

return result;

}

int Client::sendMessage(char * msg)

{

return stream.send_n(msg,ACE_OS::strlen(msg));

//return recvTask->getStream().send_n(msg,ACE_OS::strlen(msg));

}

void Client::recvMessage()

{

size_t recv_len;

char sLen[MSG_LEN_BYTES + 1];

ACE_Time_Value t(0, TIME_OUT_VALUE / 2);

stream.recv_n(sLen, MSG_LEN_BYTES, &t, &recv_len);

if (recv_len!=0)

{

sLen[recv_len]=0;

AfxMessageBox(sLen);

}

}

int Client::close()

{

recvTask->close(0);

stream.close();

return 0;

}

Client::Client()

{

}

========

为编辑框添加一个成员变量;

三个按钮代码;

连接

ACE::init();

if(Client::getInstance()->connect(20002,"127.0.0.1")==0)

{

AfxMessageBox("连接成功");

}else{

AfxMessageBox("连接失败");

}

添加到对话框实现文件头部

#include "ace/Addr.cpp"

#include "Client.h"

发送

UpdateData(true);

Client::getInstance()->sendMessage(m_send.GetBuffer(m_send.GetLength()));

“退出”按钮的代码

Client::getInstance()->close();

ACE::fini();

CDialog::OnCancel();

运行结果:

五 一个错误的解决-C2061、C2091、C2653、C2065

构建时出现下述错误,

Compiling...

WinClientDlg.cpp

c:\program files (x86)\microsoft visual studio\vc98\include\new(35) : error C2061: syntax error : identifier ‘THIS_FILE‘

c:\program files (x86)\microsoft visual studio\vc98\include\new(35) : error C2091: function returns function

......

Generating Code...

Compiling...

WinClient.cpp

Generating Code...

执行 cl.exe 时出错.

#include "ace/Addr.cpp"

#include "Client.h"

移动到对话框实现文件的最前面,再编译;

又出现,

Compiling...

WinClientDlg.cpp

C:\acedemo\demo1\WinClient\WinClientDlg.cpp(180) : error C2653: ‘ACE‘ : is not a class or namespace name

C:\acedemo\demo1\WinClient\WinClientDlg.cpp(180) : error C2065: ‘init‘ : undeclared identifier

......

C:\acedemo\demo1\WinClient\WinClientDlg.cpp(200) : error C2065: ‘fini‘ : undeclared identifier

执行 cl.exe 时出错.

此时的头文件包含代码如下;

#include "ace/Addr.cpp"

#include "Client.h"

#include "stdafx.h"

#include "WinClient.h"

#include "WinClientDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

把文件包含代码改为如下;

#include "stdafx.h"

#include "WinClient.h"

#include "WinClientDlg.h"

#include "ace/Addr.cpp"

#include "Client.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

再构建;搞定;

以下是网上关于此错误的一段论述:

VC6提示 error C2061: syntax error : identifier ‘THIS_FILE‘ 错误的解决办法

今天在编译一段以前写的代码时候,遇到了这样的错误

--------------------Configuration: AppSharePlugin - Win32 Debug--------------------

Compiling...

AppSharePluginModule.cpp

d:\program files\microsoft visual studio\vc98\include\new(35) : error C2061: syntax error : identifier ‘THIS_FILE‘

......

d:\program files\microsoft visual studio\vc98\include\memory(16) : see declaration of ‘new‘

d:\program files\microsoft visual studio\vc98\include\memory(17) : error C2809: ‘operator new‘ has no formal parameters

......

Error executing cl.exe.

AppSharePlugin.dll - 17 error(s), 0 warning(s)

双击第一个错误,居然跳转到了完全陌生的系统头文件

\microsoft visual studio\vc98\include\new(35)

中。开始怀疑是新老SDK混合引起的冲突,修改了几下参数,无果,只好向GOOGLE请教了。搜索一番之后很快明白了问题的所在,引起错误代码是这样的

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

//

//blah blah, lots of codes here

//

#include <vector>

using namespace std;

由于new已经被宏定义为DEBUG_NEW,所以在<vector>中包含的<new>中如下代码就出问题了:

void *__cdecl operator new(size_t) _THROW1(std::bad_alloc);

解决方法也很简单,把

#include <vector>

using namespace std;

两行代码,移到最前面即可!

六 安装和工程设置的文字描述

1.解压缩ace源代码包,假设在D:/ACE_wrappers

2.使用vc打开D:/ACE_wrappers/ace/ace.dsw

3.工作区上有三个工程,在ACE工程的头文件中找到config.h

4.双击打开这个文件,会有提示这个文件不存在是否创建,点是

5.在config.h中写入#include "ace/config-win32.h"表示windos 32位操作系统

6.在ACE工程上右键Settings... 选择c/c++ 在Caterory中选择 Code Generation 然后在 Use run-time library 中选择 Debug Multithreaded DLL

7.在ACE工程上右键 build(selection only)

8.编译后会在D:/ACE_wrappers/lib 目录中生成ACEd.lib ACEd.dll ACEd.exp ACEd.pdb等文件

9.D:/ACE_wrappers/ ACE-INSTALL.html有完整具体的安装指南

配置ace的工程

在使用到ace的工程中都要进行的一些设置

1.    选择Project->Settings...

2.    选择c/c++ 在Caterory中选择 Code Generation 然后在 Use run-time library 中选择 Debug Multithreaded DLL

3.    在Caterory中选择Preprocessor 在Preprocessor definitions 中添加ACE_AS_STATIC_LIBS 使用逗号与前面的内容隔开 在Additional include directories 中写入ACE的根目录D:/ACE_wrappers

4.    选择 Link 在Caterory中选择Input 在Additional library path 中加入D:/ACE_wrappers/lib 在Object/library modules 后追加aced.lib 用空格与前面的内容隔开

5.    设置完整以后重启vc

时间: 2024-10-01 13:29:55

图解VC++6.0和ACE 5.4 开发入门的相关文章

VC++6.0中OpenGL应用程序开发

1. Win32控制台方式 建立Win32 控制台程序,在头文件中加入 #include <windows.h>  #include <wingdi.h>  #include <GL/gl.h>  #include <GL/glu.h >   #include <GL/glaux.h> 2. MFC方式 (1)采用VC AppWizard向导创建空的MFC(EXE)工程框架,整个过程总共6步,值得指出的是一般情况下在向导的第1步选择创建工程的模式

VC++6.0 sqlite3 配置、测试

/************************************************************************************* * VC++6.0 sqlite3 配置.测试 * 声明: * 本文仅仅是为了测试VC++6.0中是否可以使用sqlite3数据库,主要用于完成后续的 * 一些需求. * * 2015-10-21 晴 深圳 南山平山村 曾剑锋 *************************************************

计算机二级软件VC++6.0下载地址

计算机二级软件VC++6.0介绍: 适合所有参加全国计算机等级考试的童鞋们--见图如下: 下载地址:(以下两者任选其一即可) (1).计算机二级软件VC++6.0(16.35MB) (2).计算机二级软件VC++6.0(45.26MB)(适合Windows开发软件) 计算机二级软件VC++6.0下载地址,布布扣,bubuko.com

ACE的构建(VC++6.0环境)

ACE的构建(VC++6.0环境)Windows下ACE的构建1. 将ACE-5.5.zip解压到所需的安装目录,此处以E:/为例,解压后形成ACE_wrappers文件夹,因此ACE将会存在于ACE_wrappers/ace目录中.ACE_ROOT=E:/ACE_wrappers.2. 在系统中新建ACE_ROOT环境变量,值设为 E:/ACE_wrappers.具体设置为:我的电脑->属性->高级->环境变量->新建3. 在E:/ACE_wrappers/ace目录中创建一个头

图解VC++2012编译安装GDAL1.11.0和入门例子

相关下载 http://pan.baidu.com/s/1o7OEMc6 gdal1.rar - 入门例子 GDAL书籍代码及数据.rar gdal1110.zip - 下载的源码 GDAL.rar - 构建成功后的内容 1 进入如下目录执行vcvars32.bat 2 切换到解压目录执行命令 nmake /f makefile.vc,进行编译:时间比较长:可能10几分钟: 完成编译: 3.设置输出目录 找到下载目录中的nmake.opt文件,例如本文的中的文件路径为: D:\gdal-1.11

[转]Microsoft Platform SDK 选择及在vc++6.0中的配置

Windows Platform SDK Download Sites: Windows Server 2003 PSDK February 2003 Edition,可以和VC6一起使用.并支持各种目标OS的最后一个版本的SDK. This edition of the SDK supports development for the following platforms: Windows Server 2003 Windows Advanced Server, Limited Editio

vc++6.0快捷键

Ctrl+m+Crtr+o折叠所有大纲 Ctrl+M+Crtr+P: 停止大纲显示 Ctrl+K+Crtr+C: 注释选定内容 Ctrl+K+Crtr+U: 取消选定注释内容 Ctrl+J : 列出成员 智能感知Shift+Alt+Enter: 切换全屏编辑 Ctrl+B,T / Ctrl+K,K: 切换书签开关 Ctrl+B,N / Ctrl+K,N: 移动到下一书签 Ctrl+B,P: 移动到上一书签 Ctrl+B,C: 清除全部标签 Ctrl+I: 渐进式搜索 Ctrl+Shift+I: 

【VC++6.0】成功制作并使用lib库,转载

微软有许多头文件,这些头文件里面定义了许多函数,但是在头文件中你却找不到函数内容的身影,因为函数主体被保存在了lib库中.保存在库中有一个好处,那就是源代码不容易被发现,也就是说其中的一些技术别人不容易学到.废话少说,我们现在就开始制作lib库. 首先,第一步,打开VC++6.0,按Ctrl+N,选择工程选项卡,选中“Win32 Static Library”选项,输入工程名称,我们这里用“Lib库”,大家可以自己选择,至于路径,随便选一个吧,反正这次只是lib的实验. 然后点击“确定”,我们两

在VC++6.0中给对话框设置背景色或者背景图片

/*********************************************************** *说明: 在VC++6.0中给对话框设置背景色或者背景图片 *备注:测试代码的对话框程序的工程名为:BJ *原理:在OnPaint()中加入代码 ***********************************************************/ // 注意:去掉相应以 /* */ 注释的注释符号后代码生效 void CBJDlg::OnPaint() {