CreateOleObject in a 64-bit Delphi program? - delphi

In a Delphi XE7 64-bit VCL program, the unit Vcl.OleAutocannot be found:
[dcc64 Fatal Error] Unit1.pas(33): F1026 File not found: 'Vcl.OleAuto.dcu'
While it works without problems in a 32-bit program:
uses
Vcl.OleAuto;
...
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
So how can I use CreateOleObject in a 64-bit program?

Although the source code for Vcl.OleAuto is still supplied, the 64 bit lib directory does not include Vcl.OleAuto.dcu. Instead you are expected to use System.Win.ComObj and/or System.Win.ComServ. Note that the source for Vcl.OleAuto marks that unit as being deprecated, and tells you what to use instead.
If we look through the source for Vcl.OleAuto we can find some 32 bit asm code that has not been ported. Presumably Embarcadero decided not to port this to 64 bit because the unit is deprecated.

Related

CromisIPC compilation error on DELPHI 7

I get the CromisIPC cromis ipc site download and compile/rum successfully the demos and custom project on delphi XE5. Without any error.
But, when I get the same code and put on DELPHI 7 project, I have an error on unit Cromis. AnyValue, an compilation error.
TAnyValue = packed record
private
ValueData: TValueDataType;
{$IFDEF AnyValue_HookingOff}
IntfData : IInterface;
{$ELSE}
{$IFNDEF CPUX64}
Padding : array [0..3] of Byte;
{$ENDIF}
{$ENDIF}
ValueType: TValueType;
function GetAsInt64: Int64; inline;
Exactly on lyne:
ValueData: TValueDataType;
[Error] Cromis.AnyValue.pas(210): ',' or ':' expected but identifier 'ValueData' found
[Error] Cromis.AnyValue.pas(219): 'END' expected but 'FUNCTION' found
I use delphi 7 on a 64 bits windows 7 with a 32 bits VCL project.
The same code compiles on XE5.
What happens here ? any idea ?
tl;dr This code is not designed to work under Delphi 7.
Visibility specifiers are not allowed in Delphi 7 records. The compiler is objecting to the use of private. You can remove that, but then the next problem will be all the methods that are declared on the record. Again, they are not available in Delphi 7.
You might be able to make some headway by switching from packed record to packed object. However, I think it highly unlikely that this will be smooth sailing. Expect a lot of work to make this code compile on Delphi 7. Frankly, you would need to be a Delphi expert to take on this task.
You might try to find an old version of the library that actually supports Delphi 7. You might be able to get one from the library's author. But note that the website says:
All code is Delphi 2006 and upwards compatible. I will not support older Delphi version. If you still use them, then its time to upgrade.
Which leads to the other obvious solution. Upgrade to a modern version of Delphi.
If that is impossible, then you should look for a different library.

IdStreamVCLWin32 not found error in Delphi XE4

My old Delphi 7 application is using IdStreamVCLWin32 unit in one pas file. This unit is located at following location.
C:\Program Files\Indy 10 for Delphi\Source\System\IdStreamVCLWin32.pas
When I am running same code in my Delphi XE4 environment, I am getting error IdStreamVCLWin32 not found.
Note: Delphi 7 is using Indy 10 but Delphi XE4 is using Indy which comes default with it. I have not installed indy explicitly in Delphi XE4 environment.
I searched my entire C drive where Delphi XE4 is installed but found no IdStreamVCLWin32.pas file.
How to get rid from this error?
From what I can tell, you were never meant to include that unit directly. The unit IdStreamVCL would delegate to either IdStreamVCLDotNet or IdStreamVCLWin32. And so it appears to me that IdStreamVCLWin32 is an implementation detail that you are shielded from by using IdStreamVCL.
These units have, nowadays, all been coalesced into IdStreamVCL. And so you could include that. However, it's not clear to me that you should even do that. Take a look at IdStream:
unit IdStream;
interface
{$I IdCompilerDefines.inc}
uses
{$IFDEF DOTNET}
IdStreamNET
{$ELSE}
IdStreamVCL
{$ENDIF};
type
{$IFDEF DOTNET}
TIdStreamHelper = TIdStreamHelperNET;
{$ELSE}
TIdStreamHelper = TIdStreamHelperVCL;
{$ENDIF}
implementation
end.
It seems pretty clear that you are meant to use IdStream and let the compiler work out whether that implementation is provided by IdStreamNET or IdStreamVCL.
So, the answer to your question is probably that you should replace your use of IdStreamVCLWin32 with IdStream. Note that the functionality in IdStream is implemented differently now. You no longer instantiate an instance of a stream class. The modern Indy offers you a helper class TIdStreamHelper which contains class functions. So you end up writing code like this:
BytesWritten := TIdStreamHelper.Write(Stream, Bytes, Count);
However, I cannot be sure that's the right approach since I don't know what you actually use from IdStreamVCLWin32. It's quite plausible that your code uses nothing from there and the use of IdStreamVCLWin32 is simply a stray hangover from some older version of your code.
So my advice is:
Remove IdStreamVCLWin32 from your uses.
Deal with any subsequent compiler errors by studying the code and working out the right way to do it with the current Indy code.

COM Object compiled in Delphi 2006: How to DEP enable it? [duplicate]

Delphi 2007 (and newer) supports enabling DEP and ASLR via any of these three techniques:
add the command-line switch –dynamicbase when compiling with dcc32
add the preprocessor command {$DYNAMICBASE ON} to the source code
manually OR in the bit in the header, with {$SETPEOPTFLAGS $40} in the source code
I'd like to be able to do the same thing with Delphi 2006 and C++ Builder 2006 (aka BDS 2006). Does anyone know how to do this?
Set PE flags
You can use {$SetPEOptFlags $40} to set the DEP flag, and {$SetPEOptFlags $100} to set the ASLR flag. To set both use {$SetPEOptFlags $140}.
If you have a version of Delphi with the necessary definitions in the Windows.pas unit you can use the much more readable:
{$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_NX_COMPAT or
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE }
Typically you include the $SetPEOptFlags setting in the .dpr file. And so you need to make sure that Windows is in the .dpr file uses clause for these IMAGE_XXX constants to be available.
Set DEP policy at runtime
For versions that don't support PE flag based approaches you can call this function early in your app's initialization:
procedure EnableDEP;
const
PROCESS_DEP_ENABLE: DWORD=$00000001;
var
SetProcessDEPPolicy: function(dwFlags: DWORD): BOOL; stdcall;
begin
SetProcessDEPPolicy := GetProcAddress(GetModuleHandle(kernel32),
'SetProcessDEPPolicy');
if Assigned(SetProcessDEPPolicy) then begin
//don't bother checking for errors since we don't need to know if it fails
SetProcessDEPPolicy(PROCESS_DEP_ENABLE);
end;
end;
This will work for any version of Delphi.
You cannot set the ASLR flag at runtime since it influences how the module is loaded. So ASLR can only be set using PE flags.
Modifying PE flags for very old versions of Delphi
Older versions of Delphi do not support $SetPEFlags and $SetPEOptFlags. For such versions you need to use an external tool to modify the executable post-build. When I originally wrote this answer I assumed that EDITBIN from the MS toolchain would do the job. For DEP it will suffice, using the /NXCOMPAT option. For ASLR you will need to use a different PE flag editor. My websearch revealed peflags from cygwin.
peflags --dynamicbase=true --nxcompat=true MyApp.exe
I'm sure there are other PE flag editing options available.
‘{$DYNAMICBASE ON}’ is new in Delphi2007, ‘{$SETPEOPTFLAGS $40}' was an existing directive: info
{$SetPEOptFlags $40} works in Delphi2006

Unit GIFImg was compiled with a different version of CCR.Exif.Consts.SOutOfResources

I was trying to use the EXIF library in one of my packages. It worked before but now I get strange messages:
[DCC Fatal Error] F2051 Unit GIFImg was compiled with a different
version of CCR.Exif.Consts.SOutOfResources
I don't really get it... Why Delphi tries to recompile one of its files? How do I fix this?
GifImg is located here:
c:\Program Files\Embarcadero\RAD Studio\8.0\source\vcl\GIFImg.pas
Update:
I looked at the date of that file (1 PAS and 2 DCUs) and it has the same date as any other file in RAD Studio\8.0\source\vcl folder. So, the file was not accidentally modified.
Update2:
This is my uses clause:
USES Windows, SysUtils, AnsiStrings, Graphics, Dialogs, Classes, jPeg,
pngImage,
janFX, //CCR.Exif,
{$IFDEF VER150}
GIFImageFinn {Delphi 7}
{$ELSE}
GIFImg {Delphi 2010/XE}
{$ENDIF}
;
If I comment the CCR.EXIF unit, it starts to compile my package. So, adding EXIF to my package breaks something.
What you report doesn't quite add up. The GIFImg unit that is part of the Delphi source does not refer to CCR.Exif.Consts.SOutOfResources. And none of the units used by GIFImg refer to it either.
So the explanations that seem plausible to me are:
You are including a unit called GIFImg somewhere in your project.
You've found a compiler bug.
The error message F2051 is emitted typically, in my experience, when you attempt to recompile an RTL/VCL unit but fail to set the project options to match that used by the true RTL/VCL. Alternatively it will be emitted when you recompile an RTL/VCL unit that has modifications in its interface section.
Solved:
I removed the dots in the name of the files.
CCRExif instead of CCR.Exif.
That was a nasty one.

IDE compiles successfully, but dcc32 writes: Error: E2010 Incompatible types: 'Integer' and 'NativeInt'

Delphi XE2 Update 3 IDE compiles the project successfully, but dcc32.exe writes:
Embarcadero Delphi for Win32 compiler version 22.0
Copyright (c) 1983,2010 Embarcadero Technologies, Inc.
ehshelprouter.pas(137) Error: E2010 Incompatible types: 'Integer' and 'NativeInt'
ehs_reg.pas(68) Fatal: F2063 Could not compile used unit 'ehshelprouter.pas'
Why? Line 137 is:
Application.OnHelp := OnRouteHelp; // function OnRouteHelp(Command: Word; Data: NativeInt; var CallHelp: Boolean): Boolean;
Thanks for the help!
Check the line in question. If it's saying that two types that should be compatible are incompatible, then there's something more complicated than simple assignment going on. If I had to guess, something is passing a function pointer around and the API has changed. Try checking for that case...
Your are using an older dcc32.exe by mistake (Delphi XE perhaps?). Check your PATH-setting or provide the full path to XE2 dcc32.exe in your compilation.
XE2 should display this version info:
Embarcadero Delphi for Win32 compiler version 23.0
Have you double-checked that you're not compiling for Win64 with the command line? (i.e. verify it is actually dcc32.exe that is called).
In that case NativeInt is 64bits and that would be normal to raise this error.
Also, are you trying to do a full build using the -B option like (c:\program files\embarcadero\rad studio\9.0\bin\dcc32.exe -$O- -$W+ --no-config-B-Q...) or simple compile with the -M option like (c:\program files\embarcadero\rad studio\9.0\bin\dcc32.exe -$O- -$W+ --no-config-M-Q...)?
I would also try to wipe out all the dcus to see if it helps.
And since it works from the IDE, try with capturing the command line shown in the Messages area and try that exact same line in a console.

Resources