Delphi PerlRegEx:静态链接.obj文件,因此它们不依赖于msvcrt.dll

时间:2014-03-05 20:26:47

标签: c regex delphi pcre

我已经使用了Delphi XE2中的内置RegularExpressions单元一段时间,直到我发现它的目标文件(.obj)依赖于msvcrt.dll,由{{1}包裹}。这让我有点难过,因为我总是对Delphi可以构建没有运行时依赖性的可执行文件的方式感到自豪,这与VB或VC ++(默认情况下)不同。

我尝试静态编译/链接C System.Win.Crtl文件,因此它们不依赖.obj但我的C / C ++技能有限。我尝试在Visual Studio Express中执行此操作但没有成功。有没有办法在Win32和Win64平台上实现这一目标?

我使用的msvcrt.dll版本为PerlRegEx,可在此处找到:http://www.regular-expressions.info/download/TPerlRegEx.zip7.9 2009-04-11文件位于.obj文件夹中。

pcre文件的C来源位于:http://ufpr.dl.sourceforge.net/project/pcre/pcre/7.9/pcre-7.9.zip

任何建议都将不胜感激。


我只关注exe的import表。没有看到msvcrt.dll在执行期间被加载,即使我不使用RegularExpressions单元。我在过去看到过与之相关的一些错误,并且与RegularExpressions导致msvcrt.dll被添加到导入这一事实错误相关。抱歉浪费你的时间。

1 个答案:

答案 0 :(得分:0)

这是一项非常毫无意义的任务。普通的VCL表单应用程序将加载系统msvcrt库。是的,这是一个系统库。它作为标准OS库分发。所有系统都有它。在这方面,它与user32,advapi等没有什么不同。

因此,通过删除正则表达式代码对msvcrt的依赖性将不会使您的程序具有任何更少的依赖项。更重要的是,没有什么可以害怕依赖系统库。

您可能会问为什么Delphi应用程序依赖于msvcrt。它的出现是因为:

  1. WideString类型是系统BSTR类型的松散包装。
  2. BSTR的实现由oleaut32库提供。
  3. 一个简单的vanilla Delphi程序,根本不使用任何单元,具有加载时依赖性 oleaut32,例如,SysFreeString
  4. oleaut32库反过来依赖于msvcrt。
  5. 所以,无论你做什么,你都无法消除对msvcrt的依赖。


    然而,要回答你的问题,因为我喜欢回答问题,特别是关于链接编译对象的问题,这就是你需要做的事情:

    1. 获取System.RegularExpressionsAPI.pas的副本并将其放在项目的源文件夹中。将其添加到项目中。现在这是正则表达式库的其余部分位于其上的单元。
    2. 在实施部分的顶部,删除对System.Win.Crtl
    3. 的引用
    4. 编译项​​目。
    5. 您会发现代码无法编译,并出现以下错误:

      E2065 Unsatisfied forward or external declaration: '_strncmp'
      E2065 Unsatisfied forward or external declaration: '_memmove'
      E2065 Unsatisfied forward or external declaration: '_memset'
      E2065 Unsatisfied forward or external declaration: '_memcpy'
      E2065 Unsatisfied forward or external declaration: '_memcmp'
      E2065 Unsatisfied forward or external declaration: '_strlen'
      E2065 Unsatisfied forward or external declaration: '__ltolower'
      E2065 Unsatisfied forward or external declaration: '_islower'
      E2065 Unsatisfied forward or external declaration: '__ltoupper'
      E2065 Unsatisfied forward or external declaration: '_isdigit'
      E2065 Unsatisfied forward or external declaration: '_isupper'
      E2065 Unsatisfied forward or external declaration: '_isalnum'
      E2065 Unsatisfied forward or external declaration: '_isspace'
      E2065 Unsatisfied forward or external declaration: '_isxdigit'
      E2065 Unsatisfied forward or external declaration: '_isgraph'
      E2065 Unsatisfied forward or external declaration: '_isprint'
      E2065 Unsatisfied forward or external declaration: '_ispunct'
      E2065 Unsatisfied forward or external declaration: '_iscntrl'
      E2065 Unsatisfied forward or external declaration: '_isalpha'
      E2065 Unsatisfied forward or external declaration: '_strchr'
      

      为了让编译器编译这个单元,它必须能够在修改后的System.RegularExpressionsAPI.pas单元中解析这些符号。使用System.Win.Crtl是在普通RTL中实现这一点的原因。如果您想避免链接System.Win.Crtl,那么您需要提供实现。例如,这里是_strlen

      function _strlen(P: PAnsiChar): size_t; cdecl;
      begin
        Result := System.SysUtils.StrLen(P);
      end;
      

      将其添加到修改后的System.RegularExpressionsAPI.pas单元,您已解决了依赖关系。你现在只需要为所有其他人继续这样做。这是规则,链接到编译对象票价。

      但是,正如我试图表明的那样,我不建议这样做。你正在为自己创造工作,这将无法带来明显的收益。您最终会在程序中获得比以前更多的代码。并且你有可能在实现这些C运行时函数时犯错误。你将投入大量时间,并最终得到一个比你现在更糟糕的程序。