我正在构建一个使用插件的程序.不幸的是,插件框架的动态链接迫使RTL和VCL退出我的项目EXE并进入BPL版本,并且它们没有启用调试信息.
所以我构建了一个静态链接到我的插件的测试框架,这样我就可以在跟踪代码时看到我正在做的事情.但是现在,每次我尝试重新编译时,都会收到一个错误:"unit turbu_skills是用不同版本的turbu_database.GDatabase编译的"
我以前见过这个错误,但只有当我一直在改变我可能不应该做的事情时,比如RTL或VCL库.我不明白为什么用我自己的代码做这件事.turbu_skills和turbu_database单元都是我自己编写的单元.GDatabase是一个全局单例变量,其类定义我几周没有改变.触发重新编译的任何更改都会导致此错误,即使我没有触及任何一个单元中的任何内容.
执行完整版本(SHIFT-F9)会使其正确编译.但是,如果我然后按单位(任何单位)按SPACE并按F9,我会再次收到错误.发生了什么,我该如何阻止它?这不会发生在主应用程序中,只会发生在测试框架中.
编辑:我有我所有单位的来源.删除DCU和类似文件没有帮助.将整个项目复制到另一台计算机,删除所有DCU,并在那里构建没有帮助.我的程序布局和编译器之间存在客观的,可重现的冲突,我想摆脱它.
如果有人想测试它,可以在http://www.turbu-rpg.com/downloads/Turbu_source_setup.exe找到该源代码.它需要已安装JVCL的Delphi 2009; 安装程序包将负责其余部分.也许拥有源代码可以帮助某人跟踪它.我当然希望如此,因为无论问题出在哪里,它都超越了我.问题可以在testing.exe和turbu.groupproj中的turbu.exe中找到.
编辑2:原来这是另一个跨单元泛型问题.格儿.我设法编写了一个解决方法.我希望他们很快就能解决仿制药问题.
我正在尝试修复另一个VCL错误 ; 这一次Vcl.Printers.pas.
现在我们通过将错误的VCL源文件复制到Delphi库路径中的另一个文件夹,并将修复程序应用于这些文件来实现此目的.我们将修复程序应用于TPrinter.SetPrinter.
但是文件中有六个方法用属性修饰:
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
procedure TPrinter.Abort;
begin
...
Run Code Online (Sandbox Code Playgroud)
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
procedure TPrinter.EndDoc;
begin
...
Run Code Online (Sandbox Code Playgroud)
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
procedure TPrinter.NewPage;
begin
...
Run Code Online (Sandbox Code Playgroud)
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
{$IF DEFINED(CLR)}
procedure TPrinter.SetPrinter(ADevice, ADriver, APort: string; ADeviceMode: IntPtr);
{$ELSE}
procedure TPrinter.SetPrinter(ADevice, ADriver, APort: PChar; ADeviceMode: THandle);
{$ENDIF}
var
...
Run Code Online (Sandbox Code Playgroud)
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
function SetPrinter(NewPrinter: TPrinter): TPrinter;
begin
...
Run Code Online (Sandbox Code Playgroud)
这些方法中的每一种都会引发警告:
我可以删除属性.或者可能有一种方法可以抑制警告.但我认为Embarcadero增加的属性有一些目的.
我正在尝试解决System.Classes.pas中一个已知的丑陋性能限制,它具有20世纪80年代的常量缓冲区限制($ F000),如下所示:
function TStream.CopyFrom(const Source: TStream; Count: Int64): Int64;
const
MaxBufSize = $F000;
....
Run Code Online (Sandbox Code Playgroud)
这导致我们的Delphi应用程序遭受重大性能损失.在delphi XE2到XE5中,我们能够修改它并使用以下方法之一:
我可以修改Delphi源代码,然后通过从批处理文件调用dcc32.exe,重建Delphi库文件夹中的System.Classes.dcu文件.我意识到这很难看,我不喜欢这样做,但我不喜欢RTL中这个丑陋的性能问题,而且我们的用户无法忍受它带来的性能问题.
我可以尝试在我的项目搜索路径中的某处放置一个经过修改的system.classes.pas文件.
现在,在Delphi XE6中,上述两种方法都不适合我,这可能要归功于一些内部编译器的更改.我在其uses子句中包含System.Contnrs的最小命令行应用程序中得到的错误是:
[dcc32 Fatal Error] System.Classes.pas(19600): F2051 Unit System.Contnrs was compiled with a different version of System.Classes.TComponent
Run Code Online (Sandbox Code Playgroud)
重现此问题的示例程序(假设您已修改了System.Classes.pas并更改了MaxBufSize常量),如下所示:
program consoletestproject;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Contnrs,
System.SysUtils;
var
List:System.Contnrs.TObjectList;
begin
WriteLn('Hello world');
end.
Run Code Online (Sandbox Code Playgroud)
同样,这个问题在Delphi XE6中很容易重现,但在XE5或更早版本中不是问题.
当您绝对必须使用System.Classes.pas或System.SysUtils.pas或其他一些非常低级别单元的修改副本解决基本RTL或VCL限制时,建议的做法是什么?(是的,我知道如果你不必这样做,你就不应该这样做,不要为讲课而烦恼.)
是否有一组神奇的命令行参数可以通过命令行中的"dcc32.exe"使用,以生成一个修改后的DCU,它将与上面的应用程序示例正确链接?
作为第二个问题,是否有.dcu文件没有源存在,当一个人尝试这样做时会破坏,在这种情况下,上述所有的答案是,"你无法解决这个问题,如果有一个bug在RTL中,你运气不好"?
一种可能的解决方法是在项目搜索路径(或库路径)中包含"$(BDS)\ source\rtl\common",强制每个损坏的(需要重新编译)DCU重建每个时间,但这看起来很丑陋和错误.
我需要在Classes.pas中修补一个方法
(TReader.ReadString - 我想强制它使用指定的代码页,而不是系统默认值).
如果我将Classes.pas复制到我的项目中,我最终将不得不重建整个VCL.有没有(简单)方法在运行时修补方法?