I am using Lazarus 1.0.4 with FPC 2.6
I am trying to create a TList of an own class (I just use string here, because it is more easy), but when I try to use
type
TStringList = specialize TList<string>;
it says "Specialization is only supported for generic types.
What am I doing wrong?
Might as well post it as answer, since it seems to have done the trick.
You need to use the fgl unit. See the Wiki at freepascal.org.
Related
I downloaded the OTL http://www.omnithreadlibrary.com/
and compile the D2007 grouproj, install the package, without problem.
I then create a simple console application that uses OtlParallel unit, of course, I add the OtlParallel and some other pas files to the project.
But it complains that Generics.Collections is not found.
The documentation says:
High-level abstractions are implemented in the OtlParallel unit. They are all created through the factory class Parallel. High-level code intensively uses anonymous methods and generics which makes Delphi 2009 the minimum supported version.
This us of both generics and anonymous methods makes this unit completely incompatible with Delphi 2007.
If you wish to use a construct like Parallel.For with Delphi 2007 and OTL then you will have to back-port OtlParallel yourself. Without anonymous methods this is very difficult to do and achieve the same fluid style of code. You would have to use procedural types instead of anonymous methods. And you would have to implement closures manually.
So instead of using
TProc = reference to procedure;
you would use
TMethod = procedure of object;
And then to implement this you create a class or record with a parameterless method. You'll need to add whatever state is needed as members of the type, and populate those members. That is in essence a manual implementation of a closure with variable capture. And you'll need to deal with lifetime. Make sure that the instances outlive the parallel loop.
Good luck!
I'm trying to create a shell extension to provide EXIF information for JPEG files in Windows Explorer "infotips", and am using Lazarus as this needs to produce an x64 DLL.
Does Lazarus support multiple inheritance with interfaces, and if so, how do I go about it?
for example, something like:
type
IInfoTips = interface(IPersistFile, IQueryInfo)
Thanks,
Mark
No, interfaces in FPC does not support multi-inheritance yet.
What you can do is letting the implementation class inherit from both interfaces:
type
TMyInfoTips = class(TInterfacedObject, IPersistFile, IQueryInfo)
But not at interface level, as you wish. Such statements won't compile:
type
IInfoTips = interface(IPersistFile, IQueryInfo)
You can only "inherit" from a single interface type.
Delphi does not support it either. Only the defunct Delphi for .Net compiler did... but because .Net/C# IR supports (and expects) the feature.
I'm also missing this feature in Delphi or FPC.
Both interfaces are defined in shlobj for Free Pascal/Lazarus, just like on Delphi. If symbols changed units during the Delphi lifetime, we try to put them in the more recent units, but there is a large backlog there.
All this should be largely Delphi compatible, maybe it is easier if you explained what exactly doesn't work like expected.
Added after Arnaud's comments:
No it does not. Objects implement interfaces in Pascal. I don't really understand why it is really important to do this anyway. Sure it is a bit of syntactic sugar, but since any delphi style interface implements Iunknown, you can just query an interface for another interface:
uses activex;
var x :IPersistfile;
y :IPersistStream;
begin
x.queryinterface(IID_IPersistStream,y);
end.
How to send attachment using TIdyAttachment ?
How to convert this TIdAttachment.Create(msg.MessageParts, 'c:\attach.bmp'); delphi statement to c++ builder ?
How to use this abstract class in c++ builder? Due to it's being abstract I cannot create an instance of it !!!
Note that TIdAttachment is indeed abstract (as Remy Lebeau noted in a comment). Use TIdAttachmentFile instead. In C++, I guess it should look like (Update: I see you already found that):
TIdAttachmentFile *attachment = new TIdAttachmentFile(msg->MessageParts, "C:\\attach.bmp");
FWIW, named constructor calls like TMyClass.Create(args) in Delphi are translated as new TMyClass(args) in C++Builder. That is why Delphi often overloads Create, instead of using differently named constructors like CreateWithSpecialParams. In Delphi, a constructor can have any name, but not in C++.
Note that in Delphi you can have a constructor Create(Integer) and a constructor CreateEx(Integer) and they are distinguishable. This is not translatable to C++Builder, since both translate to MyClass(int), so doing that should be avoided if the Delphi programmer wants his or her class to be usable in C++Builder.
I'm attempting to write a unit test for a simple factory class that creates one of several possible implementing objects and returns it as an interface reference.
DUnit has a built in procedure, CheckIs(AObject: TObject; AClass: TClass; msg: string), that based on its name and the parameters it accepts should fail the test if the object's class type doesn't match the expected one. The only problem is it requires an object reference not an interface reference.
So I'm trying to use CheckTrue and perform the comparison in the body of the test but I'm not as familiar with Delphi's type checking support as I am with C#'s.
I know the is operator is out of the question since it only works with object references.
CheckTrue(LMyInterfaceReference {comparison here} TMyClass);
Any suggestions?
BTW, I'm using Delphi 2009 so I don't have access to the new RTTI support added in 2010+.
I'm wondering why you MUST have to test this... maybe you really don't have to.
But if knowing the underlying object of a Interface is a must, you have two choices:
Add a method to the interface which returns the underlying object, just a TObject, and implement this in each class just by returning self.
Hack a bit, for example using this Interface to object routine.
If you don't like hacks and don't feel like upgrading to Delphi 2010+ you may use an interface like this:
IImplementingObjectInterface = interface
function GetImplementingObject: TObject;
end;
Make sure your objects also implement this interface and use it to extract the implementing object. If you need to do this for a lot of objects you can define your own TInterfacedObject derivate that already implements this so you can simply change your inheritance and be done.
Barry Kelly (one of the main Embarcadero Delphi Compiler Engineers) wrote a nice An ugly alternative to interface to object casting this week.
It answers your question.
The fun is that Hallvard Vassbotn wrote a very similar piece of code back in 2004.
From Delphi 2010 on, you can just use an is check or as cast to go back from interface references to object references.
--jeroen
I need a class that is based on TPersistent (so it stores the RTTI) and includes default Interfaces handling (QueryInterface, _AddRef, _Release) ... what is the class name I'm looking for?
whoops, nevermind, just found it - TInterfacedPersistent. What a pity Delphi lacks this kind of docs FreePascal has. Thanks God it is quite compatible