Up until now I am developing using Delphi 7. In order to pass f.e. TStringLists to my DLL's I use the FastShareMem unit as first unit in every program and dll I develop.
If I should migrate to Delphi-2010, Does FastShareMem still necessary ?
Thanks for any insight you may provide.
Short answer: No, SimpleShareMem comes with Delphi 2010
Long answer: Yes, Delphi still has its own memory manager and memory claimed from one memory manager (exe) can not be returned to another (dll). But since Delphi 2006 Delphi comes with a new memory manager called FastMM which can do the same as FastShareMem and also does not require any extra dlls to be distributed. You need to use a unit called SimpleShareMem. FastMM also has other nice features you might want to check out. FastMM is also available for Delphi 7 BTW.
You don't need to use any of those tricks if you compile with runtime packages, since the memory manager is then shared. It also comes with the advantage of sharing the same types. No more TFont can not be assigned to TFont problems. Of course this does mean you have to distribute the runtime packages.
No, use SimpleShareMem instead as first unit in your Application and DLL.
Delphi 2007 and above include now FastMM as default memory manager, which used by SimpleShareMem and no need to distribute any DLL with your application.
Related
I've been using FastMM for very long time always placing 'FastMM4' in all Delphi projects. Does it make sense with the latest Delphi versions?
It still does make sense, yes.
Delphi c.2007 starting using a version of FastMM4 as the default memory manager - but it has some stuff removed.
Continue to use the "real" version of FastMM.
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.
I have a host application, that loads a dozen of libraries at start up. I want to switch from Delphi 7s default memory manager to the full version of FastMM4 for better mem leak reporting.
Should I include FastMM4 in the uses section of both the host application and the libraries?
What about shared runtime packages?
Some added information:
We have one exe and >20 dlls. Everyone is sharing a single runtime package.
We do not use sharemem today. Not that I know about. ShareMem is not included in eighter the exe or the dlls that I had a quick look at to day.
Additional questions:
Can I use the same options inside fastmems inc file in all projects, or do the exe and the dll need different settings?
Excerpt from FastMM4options.inc file.
To me it means that if all your packages, dll's and executables are compiled with ShareMM, it should be possible to replace the Delphi 7s default memory manager.
{-----------------------Memory Manager
Sharing
Options------------------------}
{Allow sharing of the memory manager
between a main application and DLLs
that were also compiled with FastMM.
This allows you to pass dynamic arrays
and long strings to DLL functions
provided both are compiled to use
FastMM. Sharing will only work if the
library that is supposed to share the
memory manager was compiled with the
"AttemptToUseSharedMM" option set.
Note that if the main application is
single threaded and the DLL is
multi-threaded that you have to set
the IsMultiThread variable in the main
application to true or it will crash
when a thread contention occurs. Note
that statically linked DLL files are
initialized before the main
application, so the main application
may well end up sharing a statically
loaded DLL's memory manager and not
the other way around. }
{.$define ShareMM}
{Allow sharing of the memory manager
by a DLL with other DLLs (or the main
application if this is a statically
loaded DLL) that were also compiled
with FastMM. Set this option with
care in dynamically loaded DLLs,
because if the DLL that is sharing
its MM is unloaded and any other DLL
is still sharing the MM then the
application will crash. This setting
is only relevant for DLL libraries
and requires ShareMM to also be set to
have any effect. Sharing will only
work if the library that is supposed
to share the memory manager was
compiled with the
"AttemptToUseSharedMM" option set.
Note that if DLLs are statically
linked then they will be initialized
before the main application and
then the DLL will in fact share its MM
with the main application. This
option has no effect unless ShareMM is
also set.}
{.$define ShareMMIfLibrary}
{Define this to attempt to share the
MM of the main application or other
loaded DLLs in the same process that
were compiled with ShareMM set. When
sharing a memory manager, memory
leaks caused by the sharer will not be
freed automatically. Take into
account that statically linked DLLs
are initialized before the main
application, so set the sharing
options accordingly.}
{.$define AttemptToUseSharedMM}
{Define this to enable backward
compatibility for the memory manager
sharing mechanism used by Delphi 2006
and 2007, as well as older FastMM
versions.}
{$define
EnableBackwardCompatibleMMSharing}
What you're looking for is called SimpleShareMem. It's included in the FastMM package. Make sure both your app and your DLLs are using it as well as FastMM4 at the top of their uses clause. That makes sure they all share the same heap instead of using separate ones.
Of course, shared memory is only necessary if you're going to be passing dynamic memory between the app and the libraries, such as strings or objects. If not, then you don't need SimpleShareMem, but I'd still recommend to switch the libraries to FastMM as the memory manager for increased performance and improved stability.
since "Everyone is sharing a single runtime package." I'd recommend the method I'm using. Simply, add FastMM4 to your shared runtime package (Of course, you'll need to put FastMM4 in "using" declaration in each library and host application anyway).
This way has some advantages like:
simple method to switch FullDebugMode on/off [and other options of course]. No project recompilation is needed, recompiling the shared package only is enough to switch the FullDebugMode in the whole application (including dll's) as the FastMM is instanced only once.
no versioning problem. When you update FastMM (which, once used, becomes crucial component of the whole app and plugins) you don't have to ship the whole build (app & plugins) again. Once again, updating the shared package is enough.
no memory manager issues when unloading plugins. I've had some problems with FastMM being uninstalled once the first plugin library was unloaded, thus causing tons of bugs on application shutdown.
no tracking problems - in case of any memory leak or other memory issue you'll be provided with valid call stack, even if the bug occurred in the DLL code.
Here are the (non-standard) options I'm using in my FastMM4Options.inc in order to get the whole thing working as described above.
{$define NeverUninstall}
{$define UseRuntimePackages}
{.$define ShareMM}
well I believe the rest was left unchanged, but if something is wrong, here is the full file:
http://pastebin.4programmers.net/693
Afaik there is sharemm, a version of fastmm to share over DLL bounderies.
If your application is compiled with runtime packages, no additional actions are needed because runtime packages use only one memory manager, always. You just need to specify the memory manager of your choice once, preferably in the main application code as the first unit in the uses list. All the other runtime packages do not require modifications, they'll use the correct memory manager automatically, whatever that memory manager is.
If your app is compiled without runtime packages then every dll has its own memory manager. By default they all use their default memory managers, and if I'm not mistaken, it's a sharing MM, that is, you can transfer strings for example to and from dlls. If you want to replace the default MM with another sharing one, you'll need to include new memory manager as the first unit in the uses list in EVERY dll or exe you want to work together.
The difference is that with runtime packages sharing occurs at the package level. Even non-sharing MM will be shared. Without runtime packages every DLL uses a separate MM, and it's only when those separate memory managers cooperate that you get sharing.
My opinion is that unless your app interacts with dlls really closely (read: has forms and components in dlls), the best approach is not to rely on having sharing memory manager at all, but to manage your memory properly, keeping track of who creates what and deleting objects in the same library where you instantiated them. It's not hard. Just return interfaces instead of objects, return shortstrings (fixed-length) or copy the data into the provided buffer instead of returning strings, and so on. Do not return things that will be freed by the caller, don't accept things that the callee will have to free, and you'll be basically safe. Not only this solves all the possible memory manager problems, it also lets you write dlls in any language.
Ypu have two choices: keep on using the ShareMem unit and the BorldMM.dll replacement you find in the FastMM distribution, or modify both the executable and DLLs to include the FastMM memory manager, by placing the unit as the first one. You should also tailor some of the $DEFINEs you find in FastMM4Options.inc to your needs, they are well explained there. AFAIK run-time packages use the installed memory manager.
Quick one I hope - I'm just about to delve into a Delphi 5 legacy app that makes calls to a DLL (also written in D5), passing a string which the DLL can modify if required.
I have the code to both the DLL and the app. Pasted right at the top of the DLL source is a remark about using ShareMem, and it needing to be the first line in the uses clause of the project etc.
If I was porting this whole thing to D2007, is there a better (or more modern) way of getting a Delphi app to share string data with a Delphi DLL? Does the D5 ShareMem stuff still apply to Delphi 2007 applications (with FastMM etc)? I haven't even had a bash at recompiling the whole thing yet - just wondered if this bit was going to be a problem and if there was an alternative/recommended way of doing this?
FWIW, the DLL is totally first party (it's only used by this particular app - so recompiling it under D2007 as well wouldn't be a problem).
To use the FastMM included with D2007, use SimpleShareMem as the 1st unit in both your application and the DLL projects.
Or download the full FastMM4 from SourceForge, set the Flags in FastMM4Options.Inc (ShareMM, ShareMMIfLibrary, AttemptToUseSharedMM) and put FastMM4 as the 1st unit in both the application and the DLL projects.
Use only a FastMM4. FastMM4 is a great memory manager and automatically includes a ShareMem like solution! FastMM4 is compatible with D5 and up!
The reason you need sharemem is that the reference counting on ansistrings breaks when passed to a dll. One solution is :-
If you are able to restrict your strings to shortstring then you can dispense with sharemem. I have written some two dozen dlls, mostly drivers for hardware and I have not had to use sharemem once.
I'm writing delphi app which should have capability of loading plugins. I'm using JvPluginManager as plugin system/manager ;) Now, in the new plugin wizard they say it's better to use .bpl type plugins instead of .dll plugins ... What are the pros of this solution versus dll type plugins?
So far I've found only cons of this solution:
I have to put all the common interface units in separate package so that while loading plugins it won't throw any error about the other package containing common unit
if, let's say, one of plugin developers decides to uses some well-known unit (like synapse), which doesn't have runtime package by default, and the second plugin developer does the same, than bump... it's crash here ...
So, what are actually the pros of using bpls instead of dlls compiled with runtime packages?
Thanks in advance
Another disadvantage to BPL's. When you switch Delphi versions you will have to re-distribute new plugins. After many attempts at attempting to find the perfect plugin system, I ended up with COM and I have never regretted that decision. In a commercial application which has had the plugin requirement for over 8 years, the application has continued to move forward and yet some of the plugins that were released with the first iteration still exist in their ORIGINAL form.
If you choose this method, do yourself a favor and start with a simple interface and then add new interfaces upon it. You don't want to ever change your base interface, so keep it simple and sweet.
As Alexander said, a BPL is basically a DLL. But there are some conditions (from a not-so-short summary I made: http://wiki.freepascal.org/packages ):
A unit can only exist once in BPL's +Exe. This avoids duplication of state (twice the heapmanager and other global vars of system etc, VMT tables etc)
.BPL's can only USE other .BPLs.
This means that dynamic types like ansistring and IS/AS work properly over BPL interfaces.
Initialization/finalization are separate procedure and their initialization order is strictly controlled. For static dynamic loading this is simpler, for dynamic loading (plugin-like) all dependancies on units are checked .
Everything is essentially one big program, which means that the BPL's must be compiled with the same compiler version and RTL and depends on the versions other dependancies. It might be harder to make .BPL's to plugin to an existing EXE, since the Delphi version must match.
This also means that you must deliver .dcp's for (non Delphi) .BPLs the plugin .BPLs depend on
In short: if the plugin architecture is open, make it a DLL. Otherwise people have to have the exact same Delphi version to write plugins.
Hybrid is also possible. An higher level .BPL interface for functionality you factor out into .BPL yourself and selected devels, and a rock bottom procedure DLL interface for the rest.
A third option is using DLLs, but ordain Sharemem. Strings will work, multiple Delphi versions will work. Objects can work but are unsafe (e.g. I guess e.g. D2009 with an earlier version wouldn't work). Even other language users might be able to allocate over COM, not entirely excluding non Delphi.
Your first con is also a pro. If you replicate shared code in each dll the dlls get bigger and bigger. Even when using dlls you can prevent this by moving shared code in a separate dll.
Pros:
Types are shared. No TFont is not a TFont problem
Memory manager is shared. Strings and classes can be used as parameter between plugins without problems.
Cons:
Plugins can be built using Delphi or BCB only.
Plugins should use the same Delphi or BCB version.
Have you considerd using COM? COM makes it possible to share types, strings and classes and the plugins can be written in many programming languages.
I'm not familiar of JvPluginManager, but it depends on how you're going to use BPLs.
Basically, BPL - is just a usual DLL, but its initialization/finalization work is stripped from DllMain to separate functions: 'Initialize'/'Finalize'.
So, if you're going to use BPL like usual DLL, there are no cons that I'm aware of, only pros: there will be no more troubles with DllMain. That's all. The only difference.
But BPL in Delphi also provide a convient way to share code. This means great advantages (common memory manager, no duplicated code, etc, etc). So usual BPL does a lot more than "being just a DLL".
But this also means, that now your plugin system is limited to Delphi only (well, may be C++ Builder too). I.e. both plugins and exe MUST be compiled in the very same compiler to run smoothly.
If this is acceptable for you (i.e. no MS Visual Studio, no, sir, never) - then go ahead, you can use all power of BPLs.
P.S. But upgrading such BPLs plugins can be also a nightmare, if you do not design interface side carefully. In certain worst cases, you may need to recompile everything.
P.P.S. Like I said: I have no idea, how it is applied to plugins, created by JvPluginManager.
Avoid blp approach as you will have to ship a big bag of bpl with you software and thus, distribution will become bulky.
why do we use Delphi to compile small stand alone programs that just RUN anywhere without any runtime dependency. Using bpls means defeating this very purpose.
I don't know as to how comfortable you are with DLLs, but I would suggest you to use DLLs.
This will give other developers (who
may get interested in your software)
a chance to use any development
language (as long as that language
can spit out dll) to write their own
plugins that can be used in your
developed software.
Another thing is that you will be
saved from Delphi's vcl version
dependency tyranny. A major weak
point of Delphi till date.