I have been using FastMM4 version 4.92 in my Delphi 6 Pro application smoothly. I now want to use it in a package I created (BPL). I tried putting the units in the Contains section and then moving them to the top of the list but I still get the error from FastMM4 complaining that it is not the first unit to be initialized. To fix this I want to put FastMM4 in the Requires section but I can't find a DCP file for FastMM4 anywhere (runtime library). Does anyone know how to make this happen?
Probably, the reason you've got this error is that you should include FastMM4 unit not in your package, but in project where you are testing(using) your newcreated package(ofcourse on the first place in 'uses' section).
Did you set UseRuntimePackages in the FastMM4Options.inc file? Otherwise you could try to use ShareMem and the BorlndMM.dll replacement that comes with FastMM. Although ShareMem is designed for DLLs, its use should route all memory management routines to those in the BorlndMM.dll, allowing both the standard packages and yours to use FastMM code.
Related
As the title suggest, I can't find that unit.
Is there an equivalent?
I am trying to port a unit from VCL to Firemonkey which contains OleServer in its uses clause, but I can't find any information on Embarcaderos website regarding this problem.
I have also tried to Google it, but no success.
Where can I find TOleServer and/or its unit OleServer that is compatible with Firemonkey?
Or how can I implement that unit in my Firemonkey project?
Hi i have the same problèm before and i made change in OleServer
Copy Vcl.OleSever to your project and rename it to FMX.OleServer
in implementation section do change like this:
implementation
uses
FMX.Controls;
resourcestring
sNoRunningObject = 'Unable to retrieve a pointer to a running object registered with OLE for %s/%s';
at the initialization section change to FMX.Controls.TControl
initialization
GroupDescendentsWith(TOleServer, FMX.Controls.TControl);
end.
Finally rename VCL.OleServer to FMX.OleServer in your imported library unit
Indeed the main issue with compiling TLB (typelibrary) units for COM/OLE Servers seems to be some unit renaming that has occured. Ideally the Delphi IDE should detect this automatically and fix it.
Based on Doug Rudd's comment above I fixed my "uses OleServer" to "uses Vcl.OleServer" in my TLB unit.
Since there's a "source" folder under Delphi installation folder even for the Pro version now (at least at 10.2.2 Tokyo version that I'm currently using), I could also easily spot (using GrepWin free tool) where the "EmptyParam" that was causing my TLB to not compile had gone. It is under System.Variants unit that one also needs to use in their TLB (before it was in System so you didn't need to use some unit for it).
Guess I could have imported the COM/OLE Server again to make new TLB import unit, but since it was hand-ended (to remove using of "Graphics", "StdVcl" and "OleCtrls" units that were bloating the executable size in older versions of Delphi) and that hand-edited imported TLB used to work fine for a command-line application, I didn't have any reason to reimport the Type Library.
You can see the changes I did to make my XSLer tool work with the latest Delphi at https://github.com/Zoomicon/tranXform/commit/e99f42049b8a4c1534d9edb78ed5e6493e6e5786. That XSLer command-line tool is using MSXML (Microsoft XML) automation server.
I am upgrading from Delphi 6 to Delphi XE. In Delphi 6 I was using HTML help files (.chm) and used the StoHtmlHelp to make it so that I could call context sensitive help like we used to call .hlp files. I'm upgrading to Delphi XE so I need to use that native HTML help support.
I know I'm supposed to add HTMLHelpViewer to the uses clause of the project, but when I do I get a compiler warning that it couldn't find the file.
Could not compile used unit 'HTMLHelpViewer.pas'
Does anyone know why Delphi isn't finding this file by default? It should be built in.
Not being able to compile a file and not finding a file arent't the same thing. If Delphi is trying to compile HTMLHelpViewer.pas you must either:
have the vcl source folder(s) on your library path (not recommended), or
another HTMLHelpViewer.pas file is somewhere on your library path, that path comes before the standard Delphi lib folder, and that HTMLHelpViewer.pas file contains something that Delphi XE is not happy about.
The first is not likely and it would be very strange indeed if Delphi could not compile one of its units (apart from system.pas).
The second seems more likely... And if that unit used to compile, the complaints from Delphi XE could well be due to differences between Delphi 6 and Delphi XE.
You don't actually need to add it the uses clause of the .dpr file – you just need to use it from some unit in your project.
Having said that, you may actually prefer to add it to your .dpr file, and if so then do it like this:
uses
Forms,
HtmlHelpViewer,
MyUnit in 'MyUnit.pas',
I'm guessing that you have something like this:
uses
Forms,
HtmlHelpViewer in 'C:\Program Files\Borland\Delphi6\Source\VCL\HtmlHelpViewer.pas',
MyUnit in 'MyUnit.pas',
This will fail because you are asking XE to compile D6 source.
For RTL/VCL units its best to omit the path to the file and let the compiler find it (it knows where to look).
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.
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.
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.