小编Dav*_*vid的帖子

如何从Delphi程序或编译器生成的调试信息中提取局部变量信息(地址和类型)?

我的目标是:

  • 给定Delphi编译的32位或64位Windows程序中的挂起线程,以便遍历堆栈(可行)
  • 给定堆栈条目,枚举每个方法中的局部变量及其值.也就是说,至少找到它们的地址和类型(integer32/64/signed/unsigned,string,float,record,class ...),其组合可用于查找它们的值.

第一个很好,这是这个问题的第二个问题.在高级别,如何在Delphi中给出堆栈条目枚举局部变量?


在较低的水平,这是我一直在调查:

RTTI:没有列出有关方法的这类信息.这不是我实际上认为是一个现实的选择,但无论如何列在这里.

调试信息:加载为调试版本生成的调试信息.

  • 映射文件:即使是详细的映射文件(文本格式文件!打开并查看)也不包含本地变量信息.它基本上是地址列表和源文件行号.非常适合文件和行相关的地址,例如装订线中的蓝点; 不是更好的更详细的信息
  • 远程调试信息(RSM文件) - 没有关于其内容或格式的已知信息.
  • TD32/TDS文件:我目前的研究方向.它们包含许多其他信息中的全局和局部符号.

我遇到的问题是:

  • 没有TD32文件格式的文档(我可以找到.)
  • 我对它们的大部分知识来自使用它们的Jedi JCL代码(JclTD32.pas),我不确定如何使用该代码,或者那里的结构是否足以显示本地变量.我很确定它会处理全局符号,但我对本地问题非常不确定.定义了各种各样的常量,没有格式的文档,读取它们的含义,我只是猜测.但是,这些常量和它们的名称必须来自某个地方.
  • 我可以找到使用TDS信息的源不加载或处理本地符号.

如果这是正确的方法,那么这个问题变成'是否有TDS/TD32文件格式的文档,是否有任何加载局部变量的代码示例?'

代码示例不是必需的,但可能非常有用,即使它非常小.

delphi stack local-variables debug-symbols

105
推荐指数
1
解决办法
1616
查看次数

Android SQLite数据库:插入缓慢

我需要解析一个相当大的XML文件(大约在一百千字节和几百千字节之间变化),我正在使用它Xml#parse(String, ContentHandler).我目前正在使用152KB文件进行测试.

在解析期间,我还使用类似于以下的调用将数据插入SQLite数据库中:getWritableDatabase().insert(TABLE_NAME, "_id", values).对于152KB的测试文件(大约插入200行),所有这一切大约需要80秒.

当我注释掉所有插入语句(但留下其他所有内容,例如创建ContentValues等)时,同一个文件只需要23秒.

数据库操作有这么大的开销是正常的吗?我可以做点什么吗?

database sqlite performance android insert

91
推荐指数
3
解决办法
5万
查看次数

针对高度数学依赖用户编码的脚本或插件语言的建议?

我已经为这个问题开始了赏金

...因为我真的想要社区的意见.我可以(并且已经)查看了几种语言/框架,并且"好吧,这可能会正常工作" - 但我真的很感谢那些专门针对我面临的问题的建议,尤其是那些有经验整合/使用什么的人你推荐.


我从事科学分析软件的研究.它为数据的数学转换提供了许多工具.一个工具允许用户输入他们自己的等式,该等式在数据集(大的2D或3D矩阵值)上运行并进行评估.

这个工具有一个图形方程编辑器,它在内部构建一个面向对象的表达式树,每个操作都有一个不同的对象(例如,会有一个Logarithm类的实例,它是树中用于添加计算对数的节点一个值的基础;它有两个孩子作为其输入.)部分截图:

在此输入图像描述

您可以在左侧看到它正在构建的树,以及右侧菜单中的许多(五十个)潜在操作中的一些.

这有一些缺点:

  • 对于复杂的方程式,图形编辑器变得笨拙
  • 有些操作难以用图形表示,例如创建大型矩阵(例如x n卷积的内核)
  • 它只允许方程式:没有分支或其他逻辑

对于我们的用户希望能够使用它的那种东西,它更简单,但不再是更简洁.如果我现在写它我会做得完全不同 - 这是我的机会:)

我想为用户提供更强大的功能,让他们编写代码 - 脚本或编译 - 可以执行更高级的操作. 我正在寻求对这应该使用的技术或采取最佳方法的建议.

这问题的其余部分很长 - 我很抱歉.我试图详细描述这个问题.在此先感谢您阅读:)

重要限制:

  • 我们的数学运算在大型矩阵上.在上面的等式中,V1表示输入(可能是许多之一)并且是2D或3D,并且每个维度可以是大的:大约数千或数十万.(我们很少同时计算所有这些,只是片段/片段.但如果答案涉及需要编组数据的内容,请注意这个问题的大小和速度.)

  • 我们提供的操作允许您编写,比如说,2 x V将每个元素乘以V2.结果是另一个相同大小的矩阵.换句话说,一个脚本或编程语言,其中包括标准的数学元是不够的:我们需要的是能够控制哪些元可用,或如何得到实施.

    这些操作可能很复杂:输入可以像数字(2,5.3,pi)一样简单,也可以像1,2或3维矩阵一样复杂,其中包含数字,布尔复数(配对值)数据.我目前的想法是一种强大的语言,我们可以将数据类型公开为类,并可以实现标准运算符.一个简单的评估者是不够的.

    • 而不是仅仅编写迭代地在一个或多个输入上评估的操作以提供输出,如当前(可通过表达式评估器轻松实现),我希望用户能够:提供不同大小的输出到输入; 打电话给其他功能; 对于主程序,能够询问用户的代码以评估切片或输出的一部分所需的输入的哪个部分或切片将是有用的.我认为暴露我们课程的某些部分并使用OO语言可能是实现这些要点的最佳方式.
  • 我们的受众主要是研究科学家,他们不习惯编码,或者可能习惯于像Matlab或R这样的语言.

  • 我们使用Embarcadero C++ Builder 2010进行开发,使用少量Delphi.这可能会限制我们可以使用的东西 - 仅仅因为某些东西的C++,并不意味着如果它只是针对VC++或GCC进行编码就会起作用.它还必须适合与商业软件一起使用.

  • 我们的软件目前有一个COM接口,部分应用程序可以自动化,我们的应用程序是进程外的COM服务器.我们可以将COM接口添加到某些内部对象,或者如果需要,可以专门为此创建第二个COM框架.

  • 包括这个在内的"工具"正在迁移到多线程框架.最终解决方案需要能够在任何线程中执行,并且可以在多个线程中同时执行多个实例.这可能会影响托管语言运行时 - 例如,Python 2.x具有全局锁定.

  • 使用图书馆附带的语言进行数学或科学使用会很棒.

  • 向后兼容旧表达式工具并不重要.这是版本2:干净的石板!

目前的想法:

c++ delphi api plugins

48
推荐指数
4
解决办法
3092
查看次数

针对Delphi/C++ Builder的停靠库的建议?

我的团队目前正在考虑将现有的基于MDI的应用程序转移到更现代的基于对接的方法.我们仍在思考,但我们想把它转移到VS2010的对接和视觉外观上:

VS2010 UI和对接截图

这具有以下功能:

  • 显示窗口将停靠的混合轮廓
  • 划入标签,并排并排
  • 允许通过拖动和释放显示停靠位置的图像进行对接(我将其称为"停靠小部件")
  • 看起来也不错(主题/ UI方式)

我无法找到与RAD Studio 2010一起使用的高质量对接库,并且正在寻找关于我没有找到的库或者如何使用我发现的库来实现这样的建议的建议.

  • 更新:我最终购买了AutomatedQA的对接库.我认为这是最好的.有关它的部分,请参阅以下详细信息.

  • 更新2,2011年7月:这个问题考察了Delphi/C++ Builder可用的每个对接库,所以我试图让它保持最新.我知道的两个变化:
    • SmartBear现在拥有AutomatedQA,拥有终结的AutomatedQA对接库.这是我建议买的一个.他们正在考虑开源.
    • 我与DevExpress对接的一个问题(这使它不值得购买)是它缺乏对VS2008/10式对接的支持,具有对接小部件,拖动时的透明覆盖等等. 他们现在正在实现它.因此,由于AQDocking不再被出售,如果我现在问这个问题,我接受的答案就是购买DevExpress Docking.

我找到了以下库.这是一个概述:

内置VCL对接

这允许表单停靠在其他表单或TWinControls上,但看起来非常基本.使用XOR绘制的轮廓进行拖动,这在Vista和Win7上非常糟糕.有一个用于标签式停靠表单的TTabDockSet控件,但我无法弄清楚如何控制停靠表单的标题在停靠后呈现的方式.我认为并行实施对接必须手动完成,即时创建新的docksite面板.RAD Studio IDE的对接窗口比这个(例如,拖动表单时的透明矩形)有点光滑,这是奇怪的,因为我认为它使用了VCL对接支持.

JVCL对接

这看起来更像是内置VCL对接的一个不错的解决方案.它支持在任何边缘或客户端上对接,并显示表单将停靠的alphablended矩形.

JVCL对接测试程序

它似乎是非常错误的(允许在第一个表单之上删除第二个表单,但冻结程序)并且没有内置的选项卡式底座支持或任何类型的drop-location小部件.

LMD对接包

这看起来很有希望:虽然它似乎没有直接停靠表格,但它有对接面板和控件/框架.现有表单可以迁移到框架.它还有一个对接小部件和标签式底座支持.

但是,该演示似乎非常不可靠.我已经安装了最新的评估版本,并创建了一个带有停靠站点和多个面板的新项目,并按下Run会导致以下情况:

LMD对接

这在表单组件流中崩溃.目视检查DFM文件没有显示任何错误,但是有一个不透明的二进制blob用于可能导致它的布局信息.在评估版本中,这并不是特别令人鼓舞.

DevExpress ExpressDocking

我对此寄予厚望:我以前从未使用任何DevExpress控件,但他们有良好的声誉.但他们的演示程序确实令人失望:

DevExpress对接

控件很闪亮,即使使用XP风格也不太适合Windows.它确实有标签对接,但它使用XOR-ed轮廓 - 这在XP或Vista上不能很好地工作.它也没有任何类型的对接小部件.坦率地说,看起来自Windows XP时代以来它还没有更新.2011年7月更新: 这项工作正在改进中.

AutomatedQA/SmartBear对接库

到目前为止,这是所有图书馆中最有前途的.

AutomatedQA对接库

我经常使用AQTime,这是一个出色的分析器,似乎是使用自己的对接库编写的,而且效果很好.但是,最新版本的停靠库试用版下载适用于RAD Studio 2009,并且安装到2010年的建议是它不受支持,您应该重新编译源代码.该演示没有源代码,我们没有RS2009,安装程序拒绝安装,除非我们这样做,即使我们管理它安装我们也无法使用它,因为我们需要重新编译不存在的来源.

我一直与他们的支持团队保持联系,他们向我指出了这个主题.我还发现了另一个与客户提出相同问题的主题.我回复并希望听到更好的消息.我并不热衷于建议购买我无法评估的产品,特别是当我们的IDE不支持它时.

  • 更新:我最终购买了这个库.尽管有评估问题(它在D2007中工作,我有一个副本),但似乎最容易使用所有库,也是最强大的 - 例如,为它编写主题很容易.如果你还需要选择一个停靠库,我肯定会推荐它.

  • 2011年7月更新: 此库不再销售,但可能很快就会开源.

我错过了什么?

这就是我到目前为止所发现的一切.现在怎么办?

  • 我是否错过了Delphi/C++ Builder/RAD Studio 2010的任何好的对接库?
  • 我错过了目前为止我看过的图书馆的任何功能吗?答案如"你错过了FooBar"或"JVCL确实有一个对接小部件,你可以像这样使用它......"听起来真是太棒了.
  • 你下一步会推荐什么?

感谢您的输入 :)

delphi dock c++builder dockpanel-suite

47
推荐指数
2
解决办法
7706
查看次数

将大型单片单线程应用程序转换为多线程架构的建议?

我公司的主要产品是大型单片C++应用程序,用于科学数据处理和可视化.它的代码库可以追溯到12年或13年,虽然我们已经将工作投入到升级和维护中(使用STL和Boost - 当我加入大多数容器时都是自定义的,例如 - 完全升级到Unicode和2010 VCL等)还有一个非常重要的问题:它是完全单线程的.鉴于它是一个数据处理和可视化程序,这越来越成为一个障碍.

我既是开发人员下一个版本的项目经理,我们希望解决这个问题,这对于这两个领域来说都是一项艰巨的任务.我正在寻求有关如何解决问题的具体,实用和建筑建议.

程序的数据流可能是这样的:

  • 窗口需要绘制数据
  • 在paint方法中,它将调用GetData方法,通常在一次绘制操作中为数百位数据调用数百次
  • 这将从文件或其他任何需要的计算或读取(通常非常复杂的数据流 - 将此视为流经复杂图形的数据,每个节点执行操作)

即,绘制消息处理程序将在处理完成时阻止,如果数据尚未计算和缓存,则可能需要很长时间.有时这是几分钟.执行冗长处理操作的程序的其他部分也会出现类似的路径 - 程序在整个时间(有时是几小时)内没有响应.

我正在寻求如何改变这一点的建议.实用的想法.也许这样的事情:

  • 设计用于异步请求数据的模式?
  • 存储大量对象,以便线程可以安全地读写?
  • 在某些东西试图读取时处理数据集的失效?
  • 有这种问题的模式和技术吗?
  • 我应该问什么,我没有想到?

自从几年前我的Uni时代以来,我没有做任何多线程编程,我认为我团队的其他成员处于类似的位置.我所知道的是学术上的,而不是实际的,并且远远不足以让人有信心接近这一点.

最终目标是拥有一个完全响应的程序,其中所有计算和数据生成都在其他线程中完成,并且UI始终响应.我们可能无法在一个开发周期中到达那里:)


编辑:我想我应该添加一些关于该应用程序的更多细节:

  • 它是适用于Windows的32位桌面应用程序.每个副本都是许可的.我们计划将其作为桌面本地运行的应用程序
  • 我们使用Embarcadero(以前的Borland)C++ Builder 2010进行开发.这会影响我们可以使用的并行库,因为大多数似乎(?)只为GCC或MSVC编写.幸运的是,他们正在积极开发它,它的C++标准支持比以前好多了.编译器支持这些Boost组件.
  • 它的架构并不像应该的那样干净,而且组件通常耦合得太紧.这是另一个问题:)

编辑#2:感谢您的回复!

  • 令我感到惊讶的是,很多人推荐了一个多进程架构(这是目前最受欢迎的答案),而不是多线程.我的印象是,这是一个非常Unix的程序结构,我对它的设计或工作方式一无所知.Windows上有关于它的可用资源吗?它在Windows上真的很常见吗?
  • 就一些多线程建议的具体方法而言,是否存在异步请求和消费数据,线程软件或异步MVP系统的设计模式,或者如何设计面向任务的系统,或者文章和书籍以及发布后的解构说明工作的东西和不起作用的东西?当然,我们可以自己开发所有这些架构,但是与其他人之前的工作一起工作并知道要避免哪些错误和陷阱是很好的.
  • 任何答案中没有涉及的一个方面是项目管理.我的印象是估计这需要多长时间,并在做一些不确定的事情时保持对项目的良好控制,因为这可能很难.这就是为什么我会在配方或实际编码建议之后,尽可能地引导和限制编码方向.

我还没有为这个问题找到答案 - 这不是因为答案的质量,这很好(而且比你还要好),但仅仅是因为我的范围,我希望得到更多的答案或讨论.谢谢那些已经回复的人!

c++ architecture delphi multithreading c++builder

32
推荐指数
5
解决办法
3914
查看次数

在现代C++ Builder应用程序中使用预编译头文件的最佳实践是什么?

我目前正在将一个大型RAD Studio 2010项目迁移到XE4.作为其中的一部分,我正在重新创建许多项目文件.我想借此机会确保我们使用最佳的预编译头文件机制,因为似乎有几种方法可以做到这一点.

现在我们只编译32位,但将来会使用64位编译器.

以下是我们目前在2010年所做的工作,以及为什么我不确定在XE4中要做什么:

在RAD Studio 2010中

我们有一个文件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)

然后,我们在项目选项的预编译标题部分中进行以下设置:

当前RS2010预编译头设置

编译起来并不是特别快(大约350,000行代码需要12分钟.)我不确定:

  • "注入预编译头文件":这应该注入PchApp.h吗?
  • "缓存预编译头文件(必须与-H或-H"一起使用"xxx")": - H选项是"PCH文件名",因此我们正在使用它,但是预编译头的确定点是它"缓存"或每次编译预编译一次.这有什么额外的区别?
  • 我们应该在.cpp文件中包含两行包含PchApp.h和pragma hdrstop吗?有没有办法在项目选项中执行此操作,而不是在每个文件中复制这两行?他们有必要吗?

换句话说,我不确定这些是正确的还是最佳的设置,但是从阅读文档中我同样不确定什么会更好.我知道我不太了解所有选项 - 这个问题的一个原因:)

在RAD Studio XE4中

XE4 32位编译器的选项对话框是相同的,但有两件事让我感到困惑和/或让我不确定当前的2010方法是最好的.

1.默认行为

在创建新的VCL Forms项目时,IDE会创建一个默认名为Project1PCH1.h的标头,该标头旨在作为项目的预编译标头. 此标头包含<vcl.h><tchar.h>,并在项目管理器中显示为节点.它不包含在默认的Form1.cpp中,但#include <vcl.h>后面#pragma hdrstop是Form1.cpp的最顶层,后跟其他标题.

使用此标题的新项目的默认XE4设置对话框是: XE4默认预编译头设置

我(天真地?)正在假设默认值实际上是最佳/最佳设置.有些事情困扰我:

  • Project1PCH1.h在任何地方的预编译头设置中都没有提到项目的假定预编译头.
  • 标头不会被缓存
  • 未指定PCH文件名(这应该是Project1PCH1.h?)
  • .cpp文件也不包括Project1PCH1.h …

c++builder precompiled-headers c++builder-xe4

23
推荐指数
1
解决办法
1451
查看次数

实现复杂的基于旋转的摄像头

我正在实现用于空间可视化的3D引擎,并且正在编写具有以下导航功能的相机:

  • 旋转相机(即类似于旋转头部)
  • 旋转任意3D点(空间中的一个点,可能不在屏幕的中心;相机需要围绕此旋转,保持相同的相对观察方向,即外观方向也会改变.这不直接看选择的旋转点)
  • 平移在相机的平面中(因此在垂直于相机外观矢量的平面中向上/向下或向左/向右移动)

相机不应该滚动 - 也就是说,"向上"仍在继续.因此,我代表具有位置和两个角度的摄像机,围绕X和Y轴旋转(Z将滚动.)然后使用摄像机位置和这两个角度重新计算视图矩阵.这适用于平移和旋转眼睛,但不适用于围绕任意点旋转.相反,我得到以下行为:

  • 眼睛本身显然比它应该进一步向上或向下移动
  • m_dRotationX0或pi 时,眼睛根本不向上或向下移动.(万向节锁?我怎么能避免这种情况?)
  • 眼睛的旋转被反转(当它m_dRotationX在pi和2pi之间时,改变旋转使其在看起来应该向下看时向下看,当看起来应该向下看时向下看).

(a)导致这种"漂移"的原因是什么?

这可能是万向节锁定.如果是这样,标准答案是"用四元数来表示转动"说,这里的许多倍SO(1,2,3为例),但遗憾的是没有具体的细节(例如,这是最好的答案,我发现到目前为止;它很少见.)我一直在努力使用四元数结合上述两种类型的旋转来实现相机.事实上,我正在使用两个旋转来构建四元数,但是下面的评论者说没有理由 - 立即构建矩阵也没关系.

在围绕某个点旋转时更改X和Y旋转(表示摄像机外观方向)时会发生这种情况,但直接更改旋转时不会发生这种情况,即将摄像机绕自身旋转.对我来说,这没有意义.这是相同的价值观.

(b)这种相机会采用不同的方法(例如四元数)吗?如果是这样,我如何实现上述所有三个相机导航功能?

如果不同的方法会更好,那么请考虑提供该方法的具体实施示例.(我使用的是DirectX9和C++,以及SDK提供的D3DX*库.)在第二种情况下,我会在几天内添加并奖励一笔赏金,我可以在问题中添加一个.这可能听起来像我在蹦蹦跳跳,但我的时间很少,需要快速实施或解决这个问题(这是一个紧迫的截止日期的商业项目.)详细的答案也将改善SO档案,因为大多数到目前为止我读过的相机答案对代码很轻松.

谢谢你的帮助 :)


一些澄清

感谢您的评论和答案到目前为止!我将尝试澄清有关该问题的一些事项:

  • 每当其中一个变化时,从摄像机位置和两个角度重新计算视图矩阵.矩阵本身永远不会累积(即更新) - 它会重新重新计算.然而,相机位置和两个角度变量被累积(例如,每当鼠标移动时,基于鼠标上下移动的像素数量,一个或两个角度将增加或减少一小部分和/或或者在屏幕左右.)

  • 评论员JCooper声称我正遭受万向节锁定,我需要:

在变换上添加另一个旋转,在应用变换之前将eyePos旋转到完全在yz平面中,然后再旋转另一个旋转.在应用偏航 - 俯仰 - 滚动矩阵之前和之后立即围绕y轴旋转以下角度(其中一个角度需要被否定;尝试它是决定哪个角度的最快方法). double fixAngle = atan2(oEyeTranslated.z,oEyeTranslated.x);

不幸的是,当按照描述实现这一点时,由于其中一个旋转,我的眼睛以非常快的速度从场景上方射出.我确定我的代码只是这个描述的一个糟糕的实现,但我仍然需要更具体的东西.一般来说,我发现算法的非特定文本描述不如评论,解释的实现有用. 我正在为一个具体的工作示例添加一个赏金,它与下面的代码集成(也就是使用其他导航方法.)这是因为我想了解解决方案,并且有一些有用的东西,因为我因为我处于紧迫的截止日期,所以需要实施一些有效的方法.

如果你回答算法的文字描述,请确保它足够详细('旋转Y,然后变换,然后旋转'对你有意义,但缺乏细节知道你的意思. 好答案清晰,标示,即使有不同的基础,也会让其他人理解,是'坚固的防风雨信息板.')

反过来,我试图清楚地描述问题,如果我能说清楚,请告诉我.


我目前的代码

要实现上述三个导航功能,在基于光标移动的像素移动的鼠标移动事件中:

// Adjust this to change rotation speed when dragging (units are radians …
Run Code Online (Sandbox Code Playgroud)

c++ math directx matrix quaternions

22
推荐指数
2
解决办法
6774
查看次数

3D库建议用于交互式空间数据可视化?

我们的软件会生成大量地理参考和记录的数据.我们正在考虑改进可视化的方法,并在3D视图中显示(处理过的)数据,因为它的地理参考,似乎是一个好主意.

在基于Delphi-/C++ Builder的Windows应用程序中构建这些可视化时,我正在寻找有关哪些3D库最适合作为基础的SO建议.我会尽可能地加上赏金.

数据

  • 随时间记录(数小时到数天),并进行GPS标记.因此,随着时间的推移,我们有很多数据.
  • 是空间:它代表地球的真实3D元素,例如陆地,或地球周围物体的3D元素.
  • 数量很大:例如,我们可以拥有数十万到数百万点的点云.处理的数据可以显示为从这些点云创建的表面.

从中可以看出,基于空间的交互式3D可视化似乎是一种很好的方法.我正在设想一些可以轻松快速地在空间中导航的东西,数据将根据您正在查看的内容加载或生成.我希望我们不要尝试从头开始编写我们自己的3D库 - 对于这样的事情,必须有我们可以使用的良好的现有库.

所以,我希望有一个支持的库:

  • 良好的导航(例如,仅基于欧拉旋转的库?你可以选择'对象旋转或轻松移动吗?);
  • 现代GPU(仅着色器渲染是可以的;能够挂钩到管道中以编写将值映射到颜色并动态变化的着色器会很棒 - 想想通过颜色查找表给出颜色的数据值);
  • 动态数据/对象(数据可以在记录时添加;如果数据量太高,我们应该能够进出页面或重新创建它们,并且只显示一个合理的子集,以便无论用户的视口是什么at屏幕上有,但是其他数据可以加载/重新生成,最好是异步,或者至少在用户导航时很快.显然,数据创建依赖于我们,但是一个有这种东西钩子的库会很棒.)
  • 在技​​术上,与Delphi/C++ Builder和VCL一起使用.

图书馆

到目前为止,我已经考虑了两个主要的库 - 我正在寻找关于这些的知识渊博的意见,或者我没有考虑过的其他库.

1. FireMonkey

这是Embarcadero的新UI库,仅在XE2及更高版本中可用.我们的应用程序基于VCL,我们希望在VCL窗口中托管它; 这似乎是官方不支持但非正式工作正常,或通过第三方提供.

UI框架和3D框架与着色器等的混合听起来很棒.但是我不知道库是多么复杂,它对数据的支持是什么,它不是像立方体或球体那样简单的对象,以及它的设计是多么好.最后一个链接对图书馆的3D方面提出了重大批评 - 严重到足以说明我在编写一个非平凡的3D应用程序时,目前尚不确定它是否值得.

是否值得尝试使用FireMonkey在我们的VCL应用程序中编写新的可视化窗口?

2. GLScene

GLScene是Delphi着名的3D OpenGL框架.我自己从未使用它,所以没有经验,如何工作或设计.但是,我相信它可以很好地集成到VCL窗口中,并支持着色器和现代GPU.我不知道它的场景图或导航是如何工作的,或者是如何实现动态数据的.

它的功能列表特别提到了我感兴趣的一些东西,例如简单的旋转/移动,程序对象(暗示动态数据易于实现),以及用于拾取的辅助函数.似乎着色器只是Cg(不是GLSL或其他非特定于供应商的语言.)它还支持"纹理化的多态图像支持(允许多种格式以及程序纹理),易于扩展" - 这可能仅仅意味着许多图像格式,或者它可以指示可以动态改变纹理的某些东西,例如用于动态颜色映射.

从哪里来?

这是我所知道的Delphi或C++ Builder中唯一的两个主要3D库.我错过了吗?我不知道有利有弊吗?您是否有任何使用这些目的的经验,我们应该知道和使用哪些陷阱?

我们目前使用Embarcadero RAD Studio 2010,我们的大部分软件都是用C++编写的.我们有少量的Delphi,可能会考虑升级IDE,但我们最有可能等到64位C++编译器发布.因此,在RS2010中工作的库可能是最好的.

感谢您的意见:)我正在追求高质量的答案,所以我会尽可能多地加入赏金!

delphi 3d data-visualization c++builder

20
推荐指数
2
解决办法
3204
查看次数

如何在Windows 10上设置玻璃混合颜色?

在Windows 10上使用未记录的SetWindowCompositionAttributeAPI,可以为窗口启用玻璃.玻璃是白色或透明的,如截图所示:

在此输入图像描述

但是,Windows 10"开始"菜单和通知中心(均使用玻璃)都与强调色混合,如下所示:

在此输入图像描述

它是如何做到的?

调查

以下示例中的重点颜色为浅紫色 - 这是设置应用程序中的屏幕截图:

在此输入图像描述

此示例代码中定义AccentPolicy结构具有重音状态,标志和渐变颜色字段:

  AccentPolicy = packed record
    AccentState: Integer;
    AccentFlags: Integer;
    GradientColor: Integer;
    AnimationId: Integer;
  end;
Run Code Online (Sandbox Code Playgroud)

并且州可以具有以下任何值:

  ACCENT_ENABLE_GRADIENT = 1;
  ACCENT_ENABLE_TRANSPARENTGRADIENT = 2;
  ACCENT_ENABLE_BLURBEHIND = 3;
Run Code Online (Sandbox Code Playgroud)

请注意,前两个是在这个github gist上找到的.

第三个工作正常 - 这使玻璃.其他两个,

  • 无论背后是什么,ACCENT_ENABLE_GRADIENT都会产生一个完全灰色的窗口.没有透明度或玻璃效果,但绘制的窗口颜色是由DWM绘制的,而不是由应用程序绘制的.

在此输入图像描述

  • ACCENT_ENABLE_TRANSPARENTGRADIENT导致窗口完全涂上强调色,无论其背后是什么.没有透明度或玻璃效果,但绘制的窗口颜色是由DWM绘制的,而不是由应用程序绘制的.

在此输入图像描述

所以这就越来越近了,它似乎是像音量控制小程序一样使用的一些弹出窗口.

这些值不能一起排序,并且GradientColor字段的值除了必须为非零之外没有任何效果.

直接在玻璃窗口上绘图会导致非常奇怪的混合.这里用红色填充客户区(ABGR格式为0x000000FF):

在此输入图像描述

任何非零的alpha,例如0xAA0000FF,都不会产生任何颜色:

在此输入图像描述

既不匹配"开始"菜单或通知区域的外观.

这些窗户是如何做到的?

winapi aero dwm aero-glass windows-10

20
推荐指数
3
解决办法
1万
查看次数

GDI在第二个线程中使用TGIFImage处理泄漏

我有一个后台线程加载图像(从磁盘或服务器),目标是最终将它们传递给主线程进行绘制.当第二个线程使用VCL TGIFImage加载GIF图像时,每次在线程中执行以下行时,此程序有时会泄漏几个句柄:

m_poBitmap32->Assign(poGIFImage);
Run Code Online (Sandbox Code Playgroud)

也就是说,刚刚打开的GIF图像被分配给线程拥有的位图.这些都不与任何其他线程共享,即完全本地化到线程.它与时序有关,因此每次执行该行时都不会发生,但是当它确实发生时,它只发生在该行上.每个泄漏都是一个DC,一个调色板和一个位图.(我使用GDIView,它提供比Process Explorer更详细的GDI信息.) m_poBitmap32这是一个Graphics32 TBitmap32对象,但我使用普通的VCL专用类重现了这一点,即使用Graphics::TBitmap::Assign.

最终我得到一个EOutOfResources异常,可能表明桌面堆已满:

:7671b9bc KERNELBASE.RaiseException + 0x58
:40837f2f ; C:\Windows\SysWOW64\vclimg140.bpl
:40837f68 ; C:\Windows\SysWOW64\vclimg140.bpl
:4084459f ; C:\Windows\SysWOW64\vclimg140.bpl
:4084441a vclimg140.@Gifimg@TGIFFrame@Draw$qqrp16Graphics@TCanvasrx11Types@TRectoo + 0x4a
:408495e2 ; C:\Windows\SysWOW64\vclimg140.bpl
:50065465 rtl140.@Classes@TPersistent@Assign$qqrp19Classes@TPersistent + 0x9
:00401C0E TLoadingThread::Execute(this=:00A44970)
Run Code Online (Sandbox Code Playgroud)

如何TGIFImage在后台线程中解决此问题并安全使用?

其次,我会遇到PNG,JPEG或BMP类的同样问题吗?我还没有到目前为止,但鉴于它是一个线程/时间问题并不意味着如果他们使用相似的代码我就不会TGIFImage.

我正在使用C++ Builder 2010(RAD Studio的一部分.)


更多细节

一些研究表明,我不是唯一遇到这种情况的人.引用一个帖子,

Help(2007)说:在使用Lock保护画布的多线程应用程序中,所有使用画布的调用都必须通过调用Lock来保护.在使用之前没有锁定画布的任何线程都会引入潜在的错误.

[...]

但是这个陈述是绝对错误的:即使其他线程没有触摸它,你也必须在辅助线程中锁定画布.否则,画布的GDI句柄可以在主线程中随时释放(异步).

另一个回复表明类似的东西,它可能与graphics.pas中的GDI对象缓存有关.

这很可怕:在一个线程中完全创建和使用的对象可以在主线程中异步释放一些资源.不幸的是,我不知道如何应用Lock建议TGIFImage. TGIFImage没有Canvas,虽然它确实有Bitmap一个画布.锁定无效.我怀疑这个问题实际上是TGIFFrame一个内部课程.我也不知道是否或如何锁定任何TBitmap32资源.我确实尝试将TMemoryBackend位图分配给位图,这避免了使用GDI,但它没有任何效果.

再生产 …

delphi memory-leaks gdi c++builder thread-safety

16
推荐指数
1
解决办法
1560
查看次数