in C# you can easily open an assembly (just another word from an EXE) and then get reflection information from that assembly. I've been looking for something similar for Delphi where I can write a Delphi program that can point to a Delphi EXE then get me reflection information. How can I archive this? Thanks
There are a handful of programs that can extract RTTI from Delphi programs and DLLs. It's not as rich as what's available for .NET, but it can be done to a limited degree. There's a lot more RTTI available in Delphi 2010 and later versions, but as far as I know there's no program out yet that can extract info from them.
I was at the conference where this system was formally announced, and a bunch of people asked how this would affect security. Barry Kelly, who created the new RTTI, said that there would not be enough metadata available to create a "Delphi Reflector".
Well, sad news is, you probably can't. You can easily view .NET assemblies because they a) are compiled to what is called intermediate language (thus you can even get the code back using the likes of Reflector etc.), and b) contain metadata. Delphi, on the other hand, compiles to native code that and produces regular PE files that do not include rich metadata like a .NET assembly.
Delphi just doesn't work that way.
There are tools that can assist in reversing (Delphi written) executables but it will never be easy and it requires good x86 assembly knowledge.
Some examples of such tools are:
IDA Pro and/or Hex Rays
DeDe
Interactive Delphi Reconstructor
PE Explorer
The resource sections of a Delphi Executable also reveals usefull info like the form and it's components.
See also Is there a program to decompile Delphi?
If you have Delphi2010+ you can load a bpl and then use the rich rtti over it lik. e you do with c# and a .net assembly. If you need to do this in a .exe AFAIK you can't.
TestComplete seems to identify most objects in a running Delphi executable. You can extract this information with a script. A demo can be downloaded from http://www.automatedqa.com/downloads/testcomplete
This is maybe not the type of application you want as it is big and made for GUI-testing, but yes it can identify the objects.
As mentioned Remko, IDR (Interactive Delphi Reconstructor) can extract all RTTI information (if program contains it!) for Delphi version from 2 to 2009. Version 2010 will be available later. Moreover IDR can use all information that it finds in program to create a lot of comments to disassemled program code (this is a first step of analyses). You can also look forms and easy go to event hadlers associated with controls.
Related
Shapelib is a library originally written in C, which provides the ability to write simple programs for reading, writing and updating ESRI Shapefiles.
I managed to compile shapelib.dll for 32bit and 64bit on the basis of https://github.com/OSGeo/shapelib and then I wanted to test if that works with the help of ShapeFileII.pas (available in that repo).
I am using Delphi 10.3. I started with Win32 and I wrote simple program which opens .shp file and reads geometry type and coordinates. Everything worked exactly how I wanted.
Then I add Win64 platform and wanted to test it. Unfortunately, program does not work properly on Win64. I can read only geometry type, other info like coordinates etc. are mostly null.
Did someone try to use shapelib library?
Could you give me a hint? Maybe there is some distincion between Win 32/64 data types?
I appreciate any kind of help.
Update
To be more precise, I added screenshot covering the same test object on Win32 and Win64. Running on Win32 gives me values just how i want - I need especialy nVertices and padfX, padfY, padfZ. Running on Win64 gives me incorrect value of nVertices (0) and weird one-line displacement (padfX in Win32 is now padfY in Win64).
Besides eventual 32/64 bit related issues,
ShapeFileII.pas
That's a 20 years old legacy code.
I would recommend using the free ArcView ShapeFile OCX and DLL, instead.
VB6 OCX & DLL, .NET 64bit specific and AnyCPU DLLs are included.
Pascal code snippets used to be included in the library's docs, as far as I remember.
In any case better check the author's repository:
https://github.com/rosspickard/ArcShapeFile
Is it good idea to put Forms that have complete functionality in dll.
And main app will invoke dll function that returns form object.
The accepted way to do this in Delphi is to use packages rather than DLLs.
Packages are essentially DLLs but with Delphi specific capabilities that allow VCL objects to be used across package boundaries.
Trying to do this with DLLs will lead to a variety of problems that packages deal with. One downside of packages is that all modules must be compiled with the same version of Delphi. But if you are wanting to share objects across module boundaries then you would face the same restriction if you used DLLs.
The Delphi documentation has extensive coverage of packages.
Having said all that, I would add that if you can put all your code into a single module (.exe or .dll) then it does make life a lot simpler.
Adding to the answers about using packages:
Packages can only be used if both, the main app and all dlls (plugins) are written in Delphi and are written using the same version of Delphi
DLLs can be written in any programming language that can create them and can be used by any program regardless of the programming language
So, using dlls rather than packages does make sense.
Regarding the actual question: Yes, it is possible to put forms into dlls and they usually work fine. Just make sure that you do not pass them around because they are only valid objects within the context of the dll. You will experience the odd problem with forms losing focus or coming up behind other forms. This can usually be fixed by passing a window handle from the main executable to the dll which is then used as the parent for the form.
Also note: TObject of your dll is different from TObject of your application. The same applies to other commonly used classes and variables like (Forms.)Application.
I have done it and it was a pain in the lower back but it was not impossible. The main program was written in Visual Basic 6, some modules were written in Delphi 6, others were written in Delphi 7 and Delphi 2007.
Conclusion: If you are sure you will never use something different than Delphi for your app and for your dlls (plugins) and are willing to always recompile everything when you switch Delphi versions, you should use packages. Otherwise it might be better to use regular dlls. (And are you sure you will always be the only person writing these dlls? Maybe at some time there will be a 3rd party developer for one of the dlls who does not own the Delphi version he needs.)
IMO this is sometimes a very good idea and the only way to go - for the reasons others have mentioned, I'm not a fan of packages, and am very comfortable with DLL's. I am currently adding functionality to an app written in Delphi 5 using Delphi XE - it was either use DLL's or write in D5 - of course I opted for the former: D5 app calls DLL's written in XE that contain all the latest and greatest features. (The first projects I did in Delphi were done via the old Borland Paradox - Paradox app invoked DLL's written in Delphi 1!)
But, I don't send the form or module from the DLL back to the main app - I just send the DLL module a structure containing what it needs to know to do its work, and when it's done and the DLL's form closes, it cleans up and then and returns a numerical code or structure back to caller indicating success, failure etc ( old fashioned but very effective).
Passing the form instance from the DLL back to your main app across the DLL threshhold can be problematic - note #dummzeuch's excellent answer above with some good tips on how to negotiate some of those problems should you decide that is your only solution.
+1 for everything that David Heffernan says.
Strategically, you really only need to implement forms (or other functionality) in external files if you're implementing a plug in system.
If you're going to allow plugins to be authored in any language, then DLL's are the only way to go.
If your plugin system will be restricted to developers with the same version of Delphi (same team perhaps?) then go with BPL's. The additional drawback of Delphi packages, from my perspective, is the need to deploy the VCL BPL's with your app, which are always more Mb than a single compiled module.
If on the other hand you want to write a modular system, you can still do that by implementing loose coupling & "plugin" techniques within your code and still compile to a single module.
If you put a form in a normal dll the form won't be able to intercept the TAB or arrow keys. I have been told that this is due to the OnKeyDown not be passed through.
I'm trying to generate _TLB import units for Outlook 2003, 2007 and 2010 (and also other OLE servers) analogous to the ones bundled with Delphi for Outlook 2000 and 2002. However, I couldn't get the type library importer to also generate the code for capturing events from the OLE servers that is found in the bundled units. The option to "Generate component wrappers" only creates wrappers for servers that are directly instantiatable but not for objects that are only returned via methods of other objects like TInspector, TExplorer, etc.
I could of course create the event handling code myself but that would be really tedious work.
Does anyone know if the importer contained with Delphi 2010 (tlibimp.exe) can be tweaked to generate that code? I really doubt that back in the day Borland created the existing Outlook2000.pas and OutlookXP.pas units manually...
Are there maybe any other tools around that can do this?
Good question! I never noticed that those components were not created (I only use Word_TLB). After playing a bit with tlibimp I found out that you need the -Yc+ flag. Probably all ignore flags are default on.
NB: this is on Delphi 7 with tlibimp.exe version 7.0.4.453
I am looking to add the capability for users to write plugins to the program I have developed in Delphi. The program is a single executable with no DLLs used.
This would allow the user community to write extensions to my program to access the internal data and add capabilities that they may find useful.
I've seen the post at: Suggestions for Adding Plugin Capability? but its answers don't seem transferrable to a Delphi program.
I would like, if possible, to add this capability and keep my application as a single executable without any DLLs or additional modules required.
Do you know of any resources, components or articles that would suggest how to best do this in Delphi, or do you have your own recommendation?
The first question I would ask is, do you need the plugins to access the UI of your host application, or add any UI elements of their own? Or will the plugins be limited to querying and/or supplying data to your host app?
The latter is much easier and opens up two possibilities. Others have already mentioned DLLs, which is the first way to go. Certain caveats apply - in general you should be interfacing with a dll using only the data types that are used in Windows API. THat way you can be sure that the plugin DLLs will understand your data types, no matter what language/compiler they were created in. (So for example, use PChars, not strings. Do not as a rule pass Delphi classes such as TStream to a DLL. This will appear to work in some cases, but is unsafe in general, because even if the DLL was compiled in Delphi, it may have been a different version of the compiler, with a slightly different idea of what TStream is). Google for using DLLs in Delphi, and you'll find plenty more tips.
Another way that hasn't been mentioned yet is to enable scripting in your application itself. There are several very capable 3rd-party scripting engines, both commercial and free, and most of them allow you to exchange Delphi objects with the script. Some of these libraries support only Pascal as the scripting language, others will let you use Basic (perhaps better for beginner users) or other languages. See for example RemObjects Pascal Script (free) at http://www.remobjects.com/free.aspx .
My favorite scripting solution at the moment is Python for Delphi (P4D, also free) from http://mmm-experts.com/Products.aspx?ProductID=3 It can interface beautifully with your classes via RTTI, and allows you to execute Python code in your Delphi app, as well as use Delphi classes in Python scripts. Given the popularity of Python, this may be a viable solution if you want to attract developers to your project. However, every user will need to have a Python distribution installed.
It seems to me that the barrier to entry, from the point of view of potential plugin writers, is lower if you use scripting than if you choose DLLs.
Now, back to my initial question: things get much more complicated if you need the plugins to interact with your user interface, e.g. by placing controls on it. In general, DLLs cannot be used to do this. The Borland/CodeGear-sanctioned way is to use packages (BPLs). With BPLs, you can access and instantiate classes offered by a plugin as if they were declared in your host application. The catch is, all BPLs must be compiled with the same exact version and build of Delphi that your main application is. In my opinion this makes packages completely impractical, since it's hard to expect that all the potential plugin writers around the world will be using the same version of Delphi you are. A major pitfall.
To get around this, I have experimented with a different approach: keep using DLLs, and develop a syntax for the plugin to describe the UI it needs, then create the UI yourself in the host app. (XML is a convenient way to express the UI, since you get the concept of parenting / nesting for free.) The UI description syntax can include callbacks to the DLL triggered when the contents or state of the control changes. This method will restrict plugins to the set of VCL controls your application already uses or has registered, though. And it's not a one-nighter job, while BPLs certainly are.
Google for "Delphi plugin framework", too. There are some ready-made solutions, but as far as I know they usually use BPLs, with their limited usefulness.
Actually, the accepted answer to the question you cite is quite appropriate for Delphi as well. Your plug-ins will be DLLs, and you can dictate that they should export a function with a certain name and signature. Then, your program will load the DLL (with LoadLibrary) and get the address of the function (with GetProcAddress). If the DLL doesn't load, or the function isn't there, then the DLL is not a plug-in for your application.
After you have the address for the DLL, you can call it. You can pass the function an interface to something that represents the parts of your application that you wish to expose. You can also require that the function return an interface with methods that your application will call at various times.
When testing your plug-in system, it will be wise to write a plug-in yourself with a language other than Delphi. That way, you can be more confident that you haven't inadvertently required everyone to use Delphi.
At first I went for BPL and DLL base plugins. And found them hard to mantain.
If you use BPL system, then you need to match BPL version with EXE version. This includes Delphi updates which can break something. I found out (the hard way) that if I need to include all my plugins with every release, there is no point in having plugins at all.
Then I switched to plain DLL plugins. But that system just complicated code base. And that's not a good thing.
While crusing the net I found out Lua embedded script language, and delivered with it. Lua is 150K DLL, embedding bytecode compiler, interpreter and very simple and smart dynamic programing language.
My plugins are simple lua scripts. Easily mantaind and made. There are premade Delphi examples, so you can export any class or procedure as Lua table or function. GUI or not. For example I had TurboPower Abbrevia in my app for zipping. I exported my zipping class to lua, and all plugins now can call zip('.', 'dir.zip') and unzip(). Then I switched to 7zip and only implemented old class to use 7zip. All plugins work as they did, with support for new zip('.', 'dir.7z').
I made TLuaAction which calls Execute(), Update(), Hint() procedure from its script.
Lua allso have it's own plugin system that makes it easy to add funcionality to it. Eg luacom make is easy to use COM automation, luainterface allows calling .net from lua.
See luaforge for more. There is Lua IDE made in Delphi, with source.
I tried to make an overview of all such options some time ago. Together with my readers/commenters we built this list:
DLL/BPL loaded from the program.
DLL/BPL loaded from a sandbox (which could be another copy of the program or a specialized "server" application and which communicates with the main program via messages/sockets/msmq/named pipes/mailslots/memory mapped files).
COM (in any of its variants).
DDE (please not).
External program that communicates via stanard input/output.
External program that communicates via files (file name is a parameter to the program).
External program that works via drop folder (useful for batch processing).
External program that communicates with windows messages/windows sockets/msmq/named pipes/mailslots/memory mapped files/database publish-subscribe.
The most universal method of adding plug-in capability is to use COM. A good book to get you started on the road is Delphi Com Programming by Eric Harmon. While it was originally written for Delphi versions 3 through 5, the books contents are still valid with the latest versions of Delphi.
Personally, I have used this technique along with active scripting to allow end user customization.
I'm using plug-ins to implement most of the functionality in the game engine I'm building. The main EXE is made up of a script engine, a plug-in manager, some basic graphics routines and not much else. I'm using TJvPluginManager from the JEDI VCL library. It's a very good manager, and it can add just about anything you want to your program. Check out the demos included with the package to see how it works. The only downside is that it adds a lot of JCL/JVCL code to your program, but that's not really an issue if you're already using other JVCL components.
If plugins will be developed in Delphi or C++ builder, use packages + interfaces. Delphi OTA is a good example for that.
If plugins will be language independent, COM is a good way to go.
Addition: If you won't use COM, u may need to provide SDKs for each language. And datatype handling between different languages can be pain(for example delphi string type). Delphi COM support is excellent, u don't need to worry about kind of details. Those are mostly impilicit with Delphi COM support. Don't try to invent the wheel again. I'm surprised why people doesn't tend to mention about it.
I found an article by Tim Sullivan:
Implementing Plug-Ins for Your Delphi Applications
You could have a look at Hydra from Remobjects. Not only will this allow you to add plugins, but also to mix win32 and .net.
In the company that i work, we develop all the GUI in C#, but the application kernel is mainly developed in Delphi 5 (for historical reasons), with a lot of components made in COM+. Related to this very specific sort of application a I two questions:
Experienced guys in Delphi and/or COM, do you have any workrounds to work with the buggy TLB interface ?
Some of the bugs are: IDE crashing during edition of a large TLB, lost of methods IDs, TLB corruption, etc.
Here, we haven't found any good solution. Actually we tried do upgrade do the new 2007 version. But the new IDE TLB interface has the same bugs that we found before.
How do you control TLBs versions ? The TLB file is in a binary format and conflict resolutions are very hard to do. We tried to do it exporting the interfaces descriptions to IDL and commiting into CVS, but we didn't found any good way to generate TLBs from IDL using Delphi. Additionaly, the MIDL tool provided by Microsoft, didn't parse correctly the IDL files that we exported from delphi.
I think you should have a good look at Delphi 2009.
Delphi 2009 has changes to the COM support, including a text-based replacement for the binary TLB files.
You can read more on Chris Bensen's blog.
In the distant past (before I started working for CodeGear) I gave up on the odd Delphi-ized IDL language that the IDE presented, and wrote my own IDL and compiled it using MS midl. This largely worked; the only catch, IIRC, was making sure dispids (id attribute) were correct on automation interfaces (dispinterfaces) for property getters & setters - there was some invariant that tlibimp expected but midl didn't guarantee.
However, now that Delphi 2009 uses a safe subset of midl syntax, and includes a compiler for this midl in the box and integrated into the IDE, these problems should be a thing of the past.
We have also just installed Delphi 2009 and it does seem to have improved the support for Typelibraries. However I have worked with COM and type libraries for quite some time and here are my general gotchas that I have found over the years. I would agree its pretty buggy and is all the way up to Delphi 2006 (our version prior to using 2009).
Always have every file writeable before opening. This may sound obvious, but when working with source control sometimes we forget to do this and try to remove readonly flag after opening a file - Delphi cant deal with this. Ensure tlb is writable before opening.
If editing a standalone typelibrary you MUST have a project open. For some reason if you open a type library on its own it will not save. Create a blank project and then open your typelibrary. For some reason this allows the type library to be saved.
If your type library is used by an application or COM+ ensure that application is shut down or COM+ disabled before opening the type library. Any open apps will prevent the type library from being saved.
However I think your best solution is probably an upgrade. You get Unicode support too.
Using Delphi 2009 has greatly taken much of the pain out of huge TLB files, and conversion of our existing objects was painless, but our com objects don't use any third party libraries.
We will be migrating our gui applications over once the library vendors release supported versions.
Same experience with the TLB interface here: we simply stopped using it.
We work with several separate IDL files (hand-build) for different parts of our framework, making use of the #include construct to include them into the IDL of the actual application, then generate the single tlb using MIDL and tlibimp it. If the application has no IDL of it's own, pre-compiled version of the different framework TLB files are available.
Whenever the framework enters a new version, a script is run to re-generate the GUIDS on all necessary interfaces in the IDL files.
This has served us well for many years, and for us to move over the new Delphi 2009 IDL/TLB toolset will have to be not only integrated into the IDE, but also versatile when it comes to automated builds and whatnot. Can't wait to get my hands dirty with some experiments!