小编RM.*_*RM.的帖子

如何将由另一个函数返回的函数赋值给函数变量?结果而不是生成函数本身

函数返回匿名函数.我想将结果分配给变量.但是编译器认为我正在尝试分配函数而不是函数的结果.我该如何解决这个问题?

program Project9;

{$APPTYPE CONSOLE}

type
  TMyEvent = reference to function: string;

var
  v1: TMyEvent;

function GetHandler: TMyEvent;
begin
  Result := function: string
            begin
              Result := '';
            end;
end;

begin
  v1 := GetHandler;  // <- Incompatible types: 'TMyEvent' and 'Procedure'
end.
Run Code Online (Sandbox Code Playgroud)

注意:我确实有一个解决方法,但我希望在不引入包装器的情况下解决这个问题:

program Project9;

{$APPTYPE CONSOLE}

type
  TMyEvent = reference to function: string;

  TWrapper = record
    FHandler: TMyEvent;
  end;

var
  v1: TMyEvent;

function GetHandler: TWrapper;
begin
  Result.FHandler := function: string
                     begin
                       Result := '';
                     end;
end;

begin
  v1 := GetHandler.FHandler; …
Run Code Online (Sandbox Code Playgroud)

delphi variables function-pointers function anonymous-methods

16
推荐指数
2
解决办法
1471
查看次数

Delphi依赖注入:框架与委托构造器

当您可以简单地使用以下模式时,为什么要使用依赖注入框架?

unit uSomeServiceIntf;

interface

type
  ISomeService = interface
    procedure SomeMethod;
  end;

var
  CreateSomeService: function: ISomeService;

implementation

end.
Run Code Online (Sandbox Code Playgroud)
unit uSomeServiceImpl;

interface

type 
  TSomeService = class(TInterfacedObject, ISomeService)
    procedure DoSomething;
  end;

function CreateSomeService: ISomeService;

implementation 

function CreateSomeService: ISomeService;
begin
  Result := TSomeService.Create;
end;

procedure TSomeService.DoSomeThing;
begin
  ...
end;

end.
Run Code Online (Sandbox Code Playgroud)
unit uInitializeSystem;

interface

procedure Initialze;

implementation

uses
  uSomeServiceIntf,
  uSomeServiceImpl;

procedure Initialze;
begin
  uSomeServiceIntf.CreateSomeService := uSomeServiceImpl.CreateSomeService;
end;

end.
Run Code Online (Sandbox Code Playgroud)

我试图掌握使用框架而不是这样做的好处,但到目前为止我只看到了这种简单方法的好处:

1)参数化构造函数更容易实现.例如:var CreateSomeOtherService:function(aValue:string);

2)更快(容器中无需查找)

3)更简单

我就是这样用的:

unit uBusiness;
interface
[...]
implementation

uses 
  uSomeServiceIntf;
[...]
procedure TMyBusinessClass.DoSomething;
var …
Run Code Online (Sandbox Code Playgroud)

delphi dependency-injection freepascal ioc-container inversion-of-control

11
推荐指数
1
解决办法
1794
查看次数

是否可以在Delphi中为泛型类创建类型别名

我想为泛型类定义类类型(类型别名).我想这样做,因此单元b的用户可以访问TMyType而无需使用单元a.我有这样的单位:

unit a;
interface
type
  TMyNormalObject = class
    FData: Integer;
  end;
  TMyType<T> = class
    FData: <T>;
  end;
implementation
end.

unit b;
interface
type
  TMyNormalObject = a.TMyNormalObject;  // works
  TMyType<T> = a.TMyType<T>; // E2508 type parameters not allowed on this type
implementation
end.
Run Code Online (Sandbox Code Playgroud)

我已经找到了一个我不喜欢的可能的解决方法,因为它可以引入很难找到错误:

TMyType<T> = class(a.TMyType<T>); 
Run Code Online (Sandbox Code Playgroud)

这种方法的问题在于它引入了一个新的类类型,而a.TMyType实例不是b.TMyType(而a.TMyNormallClass是b.TMyNormalClass,反之亦然 - 它们指的是同一个类).

delphi generics alias types declaration

11
推荐指数
1
解决办法
3699
查看次数

有两种方法在执行DWScript时保留变量值吗?

我正在处理的应用程序允许将脚本sinppets嵌入到文档中.例如:

SomeText
<* PrintLn("This line is generated by a script"); *>
Some other text
<* PrintLn("This line is generated by a script, too"); *>
Some more lines
Run Code Online (Sandbox Code Playgroud)

结果

SomeText
This line is generated by a script
Some other text
This line is generated by a script, too
Some more lines
Run Code Online (Sandbox Code Playgroud)

我正在使用DWScript.在内部编译和执行第一个脚本片段.比下一个是RecompiledInContext并执行等等.在片段中声明的函数/变量/ etc在所有后续片段中都可用.但是,片段之间的变量值会丢失.例如:

SomeText
<* var x: Integer = 5; *>
Some other text
<* PrintLn(x); *>
Some more lines
Run Code Online (Sandbox Code Playgroud)

生成文档后:

SomeText
Some other text
0  <-- I would like this …
Run Code Online (Sandbox Code Playgroud)

delphi dwscript

9
推荐指数
2
解决办法
439
查看次数

为什么我需要在我的Delphi dll中使用Sharemem,它只使用WideString参数公开一个函数?

我有一个用Delphi编写的dll和测试应用程序.测试应用程序使用多个线程来调用dll导出的函数.导出的函数具有简单的线程安全实现.运行测试应用程序时会发生各种错误(访问冲突,无效指针操作,堆栈溢出等)或应用程序冻结.在某些情况下,应用程序完成没有错误.

请注意,这些错误仅在使用多个线程时发生(表面).从主线程调用函数时,一切正常.

我发现将ShareMem添加到dll和应用程序会停止所有这些错误.但我不明白为什么.据我所知,只有在dll和应用程序之间传递长字符串时才需要ShareMem.据我所知,WideString不是一个长字符串.

另外根据这篇文章,不应该要求ShareMem: 为什么Delphi DLL可以在不使用ShareMem的情况下使用WideString?

这是dll的来源:

library External;

uses
  Winapi.Windows;

type
  TMyType = class
  private
    FText: string;
  end;

function DoSomething(input: WideString; out output: WideString): Bool; stdcall;
var
  x: TObject;
begin
  x := TMyType.Create;
  try
    output := x.ClassName;
  finally
    x.Free;
  end;
  Result := True;
end;

exports
  DoSomething;
begin
end.
Run Code Online (Sandbox Code Playgroud)

这是测试应用程序:

program ConsoleTest;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Winapi.Windows,
  OtlParallel;

function DoSomething(input: WideString; out output: WideString): Bool; stdcall; external 'External.dll' name 'DoSomething';

var
  sResult: WideString;

begin
  try
    Parallel.&For(0, 500).Execute(procedure(value: Integer)
    var
      sResult: …
Run Code Online (Sandbox Code Playgroud)

delphi dll multithreading widestring omnithreadlibrary

9
推荐指数
1
解决办法
306
查看次数

使用Delphi,无法使用anonymus类型作为记录类型?

我不明白为什么以下小型控制台应用程序无法编译:

program Project1;

type
  TProc = reference to procedure;

  TMyRec = record
    Proc: TProc;
  end;

var
  myProc: TProc;
  myRec: TMyRec;

begin
  myProc := procedure begin writeln; end;
  myProc; // compiles fine
  myRec.Proc := procedure begin writeln; end;
  myRec.Proc; //E2014 Statement exptected, but expression of type 'TProc' found
end.
Run Code Online (Sandbox Code Playgroud)

delphi anonymous-methods

8
推荐指数
1
解决办法
213
查看次数

使用Delphi XE2在单元输出目录选项中是否可以使用项目名称?

我想创建一个通用的选项集来为我们拥有的许多项目设置基本设置,我想将每个项目的dcus指向单独的文件夹.

我想将"单位输出目录"设置为Build\dcu\$(Platform)\ $(Config)\ $(ProjectName)

现在没有$(ProjectName)这样的变量.还有别的吗?

delphi delphi-xe2

7
推荐指数
1
解决办法
1745
查看次数

Port pascal const IdentChars = ['a'..'z','A'..'Z','_']; 对C#的声明

我正在将一个Delphi应用程序移植到C#.在其中一个单位中有一个这样的声明:

const
  IdentChars = ['a'..'z', 'A'..'Z', '_'];
Run Code Online (Sandbox Code Playgroud)

我没有找到类似C#的声明语法.

这是我能想到的最好的:

char[] identFirstChars; // = ['a'..'z', 'A'..'Z', '_'];
int size = (int)'z' - (int)'a' + 1 + (int)'Z' - (int)'A' + 1 + 1; 
identFirstChars = new char[size];
int index = 0;
for(char ch = 'a'; ch <= 'z'; ch = (char)((int)(ch) + 1))
{
    identFirstChars[index] = ch;
    index++;
}
for (char ch = 'A'; ch <= 'Z'; ch = (char)((int)(ch) + 1))
{
    identFirstChars[index] = ch;
    index++;
}
identFirstChars[index] = '_'; …
Run Code Online (Sandbox Code Playgroud)

c# delphi

6
推荐指数
2
解决办法
2583
查看次数

DevExpress ExpressSkins还是VCL样式?

我正在研究用Delphi编写的大型遗留应用程序.大多数组件都是VCL和DevExpress QuantumGrid组件.我需要更新UI以支持各种样式和更现代的外观和感觉.最初我打算切换到DevExpress ExpressSkins库(我已经拥有完整的DevExpress VCL订阅)并用DevExpress组件替换所有组件.然而,因为我已经将项目升级到Delphi XE2并且随之而来的是VCL Styles技术.

这些图书馆的优点和缺点是什么?

delphi devexpress delphi-xe2 vcl-styles

6
推荐指数
1
解决办法
5106
查看次数

存储Delphi接口参考时的奇怪AV

我在以下代码中收到意外的访问冲突错误:

program Project65;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils;

type
  ITest = interface
  end;

  TTest = class(TInterfacedObject, ITest)
  end;

var
  p: ^ITest;

begin
  GetMem(p, SizeOf(ITest)); 
  p^ := TTest.Create; // AV here
  try
  finally
    p^ := nil;
    FreeMem(p);
  end;
end.
Run Code Online (Sandbox Code Playgroud)

我知道接口应该以不同的方式使用.但是我正在研究使用这种方法的遗留代码库.而且我很惊讶地发现,保留SizeOf(ITest)内存并将ITest放在那里是不够的.

现在有趣的是,如果我改变第一行

GetMem(p, 21);
Run Code Online (Sandbox Code Playgroud)

比AV消失了.(20个字节或更少的失败).对此有何解释?

(我使用的是Delphi XE2 Update 4 + HotFix)

请不要评论代码是多么可怕或建议如何正确编码.请回答为什么有必要保留21个字节而不是SizeOf(ITest)= 4?

delphi pointers interface access-violation

6
推荐指数
1
解决办法
638
查看次数