我原来一直使用Emacs开发Linux下的C++程序,但是自从我新买了电脑(硬件够快),我决定享受一下NetBeans带来的强大功能。有人说用Java开发的IDE来开发C++很奇怪,不过对我这种C++,Java程序都经常写的人,却没有这点门派之见。只要工具好用,不收费就可以。我真得觉得它比收费的VS.net要好。
编译安装最新版本的ACE
UBuntu的新立德提供的安装包总不是最新版本,太懒了。只好自己动手。首先下载最新的ACE5.7版本,然后解压为/home/chenshu/work/ACE_wrappers目录。
进入主目录:cd /home/chenshu/work/ACE_wrappers/
设置环境变量:ACE_ROOT=/home/chenshu/work/ACE_wrappers; export ACE_ROOT
添加ACE_ROOT/ace/config.h文件,加入#include "ace/config-linux.h"
添加ACE_ROOT/include/makeinclude/platform_macros.GNU文件,内容如下:
include $(ACE_ROOT)/include/makeinclude/platform_linux.GNU
设置环境变量:LD_LIBRARY_PATH=$ACE_ROOT/lib/; export LD_LIBRARY_PATH
运行make命令,等吧。
使用NetBeans6.8RC1新建一个C++应用程序
main.cpp代码修改如下:
#include
#include "ace/Log_Msg.h"
#include "ace/OS_main.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Connector.h"
#include "ace/SOCK_Stream.h"
int ACE_TMAIN(int argc, ACE_TCHAR* argv[])
{
ACE_DEBUG((LM_DEBUG, ACE_TEXT("freebird.n")));
ACE_SOCK_Connector connector;
ACE_SOCK_Stream peer;
ACE_INET_Addr peer_addr;
if (peer_addr.set(80, "192.168.22.26") == -1)
return 1;
else if (connector.connect(peer, peer_addr) == -1)
return 1;
}
设置工程属性的include路径和lib路径,添加链接的库文件。如下图:
在上面的对话框中,Libraries点击按钮,选择添加库文件,然后添加编译出来的ACE的动态库
ok,程序可以编译和调试了。
传说中的ACE CDR的bug如何了?
我在博客http://blog.csdn.net/fullsail/archive/2008/09/12/2915667.aspx看到关于ACE的"bug"的。我测试了网上提供的例子代码,略作修改,结果ACE5.7中情况仍然是写入和读取的数据不一致。
#include
#include "ace/Log_Msg.h"
#include "ace/OS_main.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Connector.h"
#include "ace/SOCK_Stream.h"
#include "ace/CDR_Stream.h"
#include
using namespace std;
int ACE_TMAIN(int argc, ACE_TCHAR* argv[])
{
char* pBuffer=new char[2048];
char* pStart=pBuffer+1;
ACE_OutputCDR output_cdr(pStart,512);
ACE_InputCDR input_cdr(pStart,512);
ACE_CDR::ULong cdr_long = 123;
bool bret =false;
bret = output_cdr.write_ulong(cdr_long);
bret = input_cdr.read_ulong(cdr_long);
cout<
}
我的疑问是ACE经历了这么长时间,怎会出现这么容易被发现的bug呢?是不是我们不应该这样用呢?默认情况下,我们没有定义宏ACE_CDR_IGNORE_ALIGNMENT,ACE就会进行字节边界对齐操作。如果我们用原始的buffer构造ACE_OutputCDR对象,CDR会在发现不对齐的方式下进行缓冲区起始位置后移,然后才开始写入数据。所以,这时候真正的有效数据起始位置应该不是pStart所指的地方,应该在后面一点。我们在构造ACE_InputCDR对象的时候,第一个参数也应该给有效位置,而不是pStart。现在我把代码稍微改动一下,就得到正确的数值了。
ACE_InputCDR input_cdr(pStart,512);被替换成了
ACE_InputCDR input_cdr(output_cdr.buffer(),512);
我一直没有碰到这个"bug"是因为我的程序从来没有用原始buffer进行构造,我也不推荐这样做。让ACE自己去管理起始位置,如果真要获取,我们应该调用ACE类的函数获得,而不要假定一定在开始。或许就是因为只要正确使用就能绕过这个"bug",因此也就没有被Daglous视为真正的bug。这可以称之为一个陷阱。C++总是充满各种陷阱的,不是么?