我目前正在将一个大型RAD Studio 2010项目迁移到XE4.作为其中的一部分,我正在重新创建许多项目文件.我想借此机会确保我们使用最佳的预编译头文件机制,因为似乎有几种方法可以做到这一点.
现在我们只编译32位,但将来会使用64位编译器.
以下是我们目前在2010年所做的工作,以及为什么我不确定在XE4中要做什么:
我们有一个文件PchApp.h,其中包含<vcl.h>许多其他常用的头文件,主要是项目中各种常用核心类的头文件.此标头包含在每个CPP文件的顶部,后跟#pragma hdrstop如下所示:
// Top of .cpp file
#include "PchApp.h"
#pragma hdrstop
// Normal includes here
#include "other.h"
#include "other2.h"
// etc
Run Code Online (Sandbox Code Playgroud)
然后,我们在项目选项的预编译标题部分中进行以下设置:

编译起来并不是特别快(大约350,000行代码需要12分钟.)我不确定:
换句话说,我不确定这些是正确的还是最佳的设置,但是从阅读文档中我同样不确定什么会更好.我知道我不太了解所有选项 - 这个问题的一个原因:)
XE4 32位编译器的选项对话框是相同的,但有两件事让我感到困惑和/或让我不确定当前的2010方法是最好的.
1.默认行为
在创建新的VCL Forms项目时,IDE会创建一个默认名为Project1PCH1.h的标头,该标头旨在作为项目的预编译标头. 此标头包含<vcl.h>和<tchar.h>,并在项目管理器中显示为节点.它不包含在默认的Form1.cpp中,但#include <vcl.h>后面#pragma hdrstop是Form1.cpp的最顶层,后跟其他标题.
使用此标题的新项目的默认XE4设置对话框是:

我(天真地?)正在假设默认值实际上是最佳/最佳设置.有些事情困扰我:
Project1PCH1.h在任何地方的预编译头设置中都没有提到项目的假定预编译头.Project1PCH1.h?)Project1PCH1.h …我已将项目从RAD Studio 2010升级到RAD Studio XE4.该项目主要是使用C++ Builder的一半RAD Studio进行的C++,其中包括Delphi的一些内容.
在2010年,Release版本为22MB.在XE4下,相同的Release版本为55MB.
这是一个问题,因为:
是什么导致这种情况,我该如何解决?
<UsePackages>True</UsePackages>Release not Debug中存在的东西; 删除它没有任何区别.除此之外,还启用了代码优化,缺少_DEBUG定义.{$WEAKLINKRTTI ON}.该XE4文件没有提到一个相当的C++编译链接.有#pragma explicit_rtti(C++类似物{$RTTI})和__declspec(delphirtti)(C++类似物{$M}/{$TYPEINFO}).我msbuild在RAD Studio XE4中遇到了一些奇怪的错误,我正在寻求帮助来诊断正在发生的事情.我已经遇到了这个问题已经有几个星期了,但是我自己也没有成功解决这个问题 - 时间问得更广泛了.症状是:
msbuild Project.cbproj似乎可以正常工作msbuild Project.cbproj /t:Clean,并删除中间文件.输出的可视扫描不显示任何异常文件被删除 - 只有.obj文件,链接器状态文件,最终EXE等.msbuild Project.cbproj /t:Build或只是简单失败,并显示以下错误消息:msbuild Project.cbprojMicrosoft(R)Build Engine版本3.5.30729.5420 [Microsoft .NET Framework,版本2.0.50727.5472]版权所有(C)Microsoft Corporation 2007.保留所有权利.
Build build 12/09/2013 10:35:03.节点0上的项目"C:\ projects\Project.cbproj"(默认目标).
_PasDepCheck:已修改:Source\Common\resample.pas _PasCoreCompile:Embarcadero Delphi for Win32编译器版本25.0版权所有(c)1983,2013 Embarcadero Technologies,Inc.C:\ Program Files(x86)\ Embarcadero\RAD Studio\11.0\Bin\CodeGear.Cpp.Targets(191 1,5):错误F1026:找不到文件:'True.dpr'完成构建项目"C:\ projects\Project.cbproj"(默认目标) - 失败.
建立失败.
"C:\ projects\Project.cbproj"(默认目标)(1) - >(_PasCoreCompile目标) - > C:\ Program Files(x86)\ Embarcadero\RAD Studio\11.0\Bin\CodeGear.Cpp.Targets(1 911,5):错误F1026:找不到文件:'True.dpr'
Run Code Online (Sandbox Code Playgroud)0 Warning(s) 1 Error(s)
有些事情让我觉得这个:
True.dpr不存在,也无法找到手动搜索.cbproj文件True.dpr的True …我正在实现一个客户端应用程序,它必须与硬件设备建立少量套接字连接.我已将问题分解为以下小代码子集
boost::system::error_code ec;
std::string str_message = ec.message(); // no access violation before connect()
std::string str_port = "502";
std::string str_ip = "192.168.12.198";
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(),str_ip,str_port);
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::ip::tcp::socket s(io_service);
ec = s.connect(*iterator,ec);
if (ec)
{
// connection error of some kind.
std::string str_debug = ec.message(); // BANG!!!!
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Embarcadero RAD studio XE4 C++ Builder,当我在主VCL线程中运行上面的代码时,它运行正常.当我和多个连接运行它,我上面的代码中的多个实例运行TThread类,这是当我进入访问冲突的问题-它似乎是,当error_code被修改的connect电话,该内部构件m_cat中的error_code实例变为NULL,所以当我打电话时,message()我得到访问冲突.即使我只运行一个后台线程,也会发生这种情况.
上面的代码是否有可能在我需要使用它的方式上不是线程安全的?我试图找出为什么这个代码不会在后台线程中运行,但找不到任何关于它的东西.
我运行的升级版本是1.50,因为这是用于在RAD studio中构建64位应用程序的集成版本.
是否有其他人在多线程设置(Embarcadero或其他)中遇到此问题,如果是这样,你是如何解决它的?或者这个类是不安全的以多线程方式使用?
我boost::asio用来与同一台计算机上运行的node.js TCP服务器应用程序建立同步TCP套接字连接.我在Windows上使用Embarcadero RAD studio XE4构建64位应用程序,该应用程序使用Embarcadero集成升级版本1.50.
除了node.js TCP服务器关闭之外,工作正常.发生这种情况时,我从套接字读取时,我的C++客户端应用程序没有检测到断开连接.但是,当我写入套接字时,它确实检测到断开连接.
我目前的代码是在尝试了解增强文档和SO上的各种答案之后编写的.代码的读取部分如下(我省略了检查紧凑性的错误代码)
boost::system::error_code ec;
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket s(io_service);
boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"),m_port);
ec = s.connect(ep,ec);
std::size_t bytes_available = s.available(ec);
std::vector<unsigned char> data(bytes_available,0);
size_t read_len = boost::asio::read(s, boost::asio::buffer(data),boost::asio::transfer_at_least(bytes_available),ec);
if ((boost::asio::error::eof == ec) || (boost::asio::error::connection_reset == ec))
{
// disconnection
break;
}
Run Code Online (Sandbox Code Playgroud)
这不是一个很好的系统,因为它在循环内部运行自己的线程并不断轮询数据直到程序关闭.通常情况下,read()当没有数据时我不会在套接字上执行,但在这种情况下我会这样做,因为所有文档都让我相信只有在执行读取或写入套接字时才会检测到套接字断开连接.问题是上面的代码在node.js应用程序关闭时根本不会检测到断开连接.如果我正在编写,我会检测到它(代码的写入部分使用与读取相同的boost :: asio :: error`错误),但在读取时却没有.
显然,我无法执行大于可用字节数量的读取,或者我的线程将阻塞,我将无法在我的线程循环中执行写入.
我错过了另一个特定的增强错误代码来检测错误情况吗?或者这是一个特别是零长度读取的问题.如果是这样的话,我还有其他选择吗?
目前我正在让node.js服务器在关闭时关闭我检测到然后自己关闭客户端的时候写入特定的消息.但是,这有点像黑客,如果可能的话,我更愿意采用干净的方法来检测断开连接.