I am interested in upgrading a suite of software from ODAC v5 to v8.2.8.
One app in particular is causing problems. This application loads one of a set of secondary applications implemented as dlls.
LibHandle := LoadLibrary(PChar(dllname));
if LibHandle <> 0 then
begin
#showForm := GetProcAddress(LibHandle,'ShowMainDllForm');
if (#showForm <> nil) then
begin
try
ShowForm(Application.Handle, #FGlobalVars, 1);
The launcher is fine - it has its own database connection, and I can step through the various ODAC units fairly happily.
However, the dll immediately excepts on attempting to open a cursor. The error is an Assertion Failure in the unit DBAccess.pas, called from MemDs.pas. I have stepped through this and have shown that the assertion failure is correct; Assert(FieldDesc is TCRFieldDesc) is receiving a TFieldDesc from MemDS.CreateFieldDefs().
I am stumped. How can it be that one calling method works fine (the launcher app) and the other (the dll) always fails ?
If anyone has experienced difficulties in this area I would appreciate any information, however tenuous it might sound
We have already fixed this problem. You can either download the latest ODAC version 8.6.12 or modify the line invoking Assert:
in the TCustomDADataSet.GetFieldType method
replace
Assert(FieldDesc is TCRFieldDesc);
with
Assert(IsClass(FieldDesc, TCRFieldDesc));
we use the DEVART MySQL, and SQL connectors. I have experienced the exact issue with the MySQL (MyDAC) connection. However, what I found was this:
In the DBAccess.pas file, the above code change was already there;
Assert(IsClass(FieldDesc, TCRFieldDesc));
But I was still getting the same Assertion error. I stepped in a little further, and found in the CRFunctions unit, I made the following changes, and now my Server connection works perfectly from a dll file:
begin
if IsLibrary then
Result := IsClassByName(Obj, AClass)
else
//------------------------------------
// Danny MacNevin : October 3,2013
// commented out the below line to fix an Assertion Error
// using the TMyConnection in a dll file.
// It was being called from the DBAccess.pas file at line: 7251
// To put this file back to normal, remove the line I added, and
// uncomment the line below...
//------------------------------------
//Result := Obj is AClass;
Result := IsClassByName(Obj, AClass) //Line replaced by Danny
end;
Related
I have a minimalist project with FireDac FDConnection & FDSqlQuery,
DataSetProvider and ClientDataSet, trying to access the example
Employee.FDB that came with the Firebird 2.5 package I downloaded
from SourceForge today.
Everything is set to the defaults as theycame off the palette apart from the database name in the FDConnection's pop-up Information tab and the FDQuery's Sql, which is set to select * from employee.
The FDQuery opens fine but as soon as I try
to open the CDS, in the IDE or running my app, I get an access violation.
This is all my code:
FDQuery1.Open;
Caption := IntToStr(FDQuery1.RecordCount); // this shows 42 on the form's caption
CDS1.Open; // AV here
So, the FDQuery opens ok but the CDS doesn't.
At run time, the exception occurs here:
function TCustomClientDataSet.CreateDSBase: IDSBase;
begin
CreateDbClientObject(CLSID_DSBase, IDSBase, Result);
Check(Result.SetProp(dspropANSICODEPAGE, DefaultSystemCodePage)); <-- Exception here
Check(Result.SetProp(dspropUTF8METADATA, NativeUInt(True)));
Check(Result.SetProp(dspropUTF8ERRORMSG, NativeUInt(True)));
end;
The exception msg is
Project FBTest1 raised exception class $C0000005 with
message 'access vioaltion at 0x0075d05b: read of address 0x00000000'.
In the IDE I get a similar exception if I try to set Active = True on the CDS,
which the message said occurred in DSnap200.Bpl.
The first time it happened at run-time I had some kind of "Incident Report" pop-up
offering to report it to Embarcadero. First time I've seen that.
If I substitute a SqlConnection and SqlQuery for the FDac components, I get
the same error.
So, I guess my question is, can a CDS be provoked into this behaviour simply by using default property settings for a project as simple as this one, i.e. did I miss a step, or is it likely an EMBA QC thing?
Solved! Thanks to Graymatter's suggestion to try Using MidasLib, I've got
to the bottom of the problem and fixed it so that the app now works using Midas.Dll. I'm posting this as an answer, rather than a comment, firstly because it's a bit too long for that, but, more importantly, the cause was actually rather strange and the solution may assist anyone else who runs into the problem.
First, I tried Using MidasLib, and the app ran fine, w/o the AV that the q is about.
So, reassured that the problem doesn't arise with the current MidasLib code, I went
back to trying to get the app to work with Midas.Dll. I checked the Midas.Dll
versions in the XE6 bin directory and \Windows\SysWOW64, and they were both as I
was expecting, 20.0.16277.1276 dated 16 June 2014.
Tracing into CheckDBlient in DataSnap.DSIntf and observing carefully, the penny
dropped and I realised what was happening:
procedure CheckDbClient(const CLSID: TGUID);
[...]
begin
[...]
if DbClientHandle = 0 then
begin
Size := 256;
SetLength(FileName, Size);
if RegQueryValue(HKEY_CLASSES_ROOT, PChar(Format('CLSID\%s\InProcServer32',
[GUIDToString(CLSID)])), PChar(FileName), Size) = ERROR_SUCCESS then
SetLength(FileName, Size) else
begin
[...]
end;
DbClientHandle := LoadLibrary(PChar(FileName));
This gets the path to Midas.Dll from the InProcServer key in its registration, and this
wasn't pointing to XE6's bin directory or SysWOW64, but to another location that was not
of my creation and which contained a version of Midas.Dll dating from 2007. Oddly, unlike a copy I have of the Dll dating from the D7 era, this Dll does not have version info on its property page but it has a creation date of 9 August 2002 and a file size of 351Kb.
So, once I'd found that, fixing the problem was as simple as renaming that Dll so that
the OS won't load it, and re-registering the version in SysWOW64.
Where the rogue Midas.Dll came from isn't clear, but it certainly arrived since
last week, because it isn't in the back-up I happen to have from last Thursday evening.
The only things I've installed since then are a handful of 3rd-party GUI utilities for
managing/accessing Access, IB and Firebird databases, so the culprit seems to have been
one of them.
In my project, i'm trying to connect one more UNIT, named Lang_Unit.pas with some classes and procedures, but, while compiling the Project, Delphi gives unknown error called "[dcc32 Fatal Error] Lang_Unit.pas(5): F2084 Internal Error: AV07953449-R26D7474C-0".
And the point is that, what if i will close my project, or remove this connected UNIT, error is not getting away.
And if i will create clear default VCL Application, its still gives this error.
And only when i'm restarting my Delphi 2010, error is getting away.
But, if i will try to edit something in the code, this error is comes again...
What is problem ? Everything was works fine, im not touched nothing.
I've just turned off my PC, then after some time turned it ON and opened my Project and edited my code, then i see this error...
If Its will help, here is my Lang_Unit.pas code :
unit Languages_UNIT;
interface
Uses
System.Generics.Collections, IniFiles;
Type
TLanguages_List = Class
private
LangType:string;
LangDescription:string;
LangFile:TIniFile;
public
Constructor Create(LType,LDes:string; LFile:TiniFile);
Function GetLangType:string;
Function GetDescription:string;
Function GetStructure:TIniFile;
End;
TLanguages_Controller = Class
public
Function GetStructureByType(RequestedType:string; LangList:TObjectList<TLanguages_List>):TIniFile;
Function TypeExists(RequestedType:string; LangList:TObjectList<TLanguages_List>):Boolean;
Procedure LoadLanguage(RequestedType:string; LangList:TObjectList<TLanguages_List>);
End;
implementation
uses Unit1;
Constructor TLanguages_List.Create(LType,LDes:string; LFile:TiniFile);
Begin
LangType:=LType;
LangDescription:=LDes;
LangFile:=LFile;
End;
Function TLanguages_List.GetLangType:string;
Begin
Result:=LangType;
End;
Function TLanguages_List.GetDescription:string;
Begin
Result:=LangDescription;
End;
Function TLanguages_List.GetStructure:TIniFile;
Begin
Result:=LangFile;
End;
Function TLanguages_Controller.GetStructureByType(RequestedType:string; LangList:TObjectList<TLanguages_List>):TIniFile;
var
i:integer;
Begin
For i := 0 to LangList.Count-1 Do
Begin
IF(LangList[i].GetLangType=RequestedType) Then
Begin
Result:=LangList[i].GetStructure;
Break;
End;
End;
End;
Function TLanguages_Controller.TypeExists(RequestedType:string; LangList:TObjectList<TLanguages_List>):Boolean;
var
i:integer;
GOTYA:Boolean;
Begin
GOTYA:=False;
For i := 0 to LangList.Count-1 Do
Begin
IF(LangList[i].GetLangType=RequestedType) Then
Begin
GOTYA:=True;
Break;
End;
End;
IF(GOTYA) Then
Result:=True
Else
Result:=False;
End;
Procedure TLanguages_Controller.LoadLanguage(RequestedType:string; LangList:TObjectList<TLanguages_List>);
var
i:integer;
SLS:TIniFile;//SELECTED LANGUAGE STRUCTURE
CS:string;//CURRENT SECTION
Begin
//GET SELECTED LANGUAGE STRUCTURE
For i := 0 to LangList.Count-1 Do
Begin
IF(LangList[i].GetLangType=RequestedType) Then
Begin
SLS:=LangList[i].GetStructure;
Break;
End;
End;
//START LOADING SELECTED LANGUAGE
//TABS SECTION LOAD
CS:='TABS';
SD_DEFNAME:=SLS.ReadString(CS,'Speed_Dials','Speed_Dials');
Form1.goleft.Hint:=SLS.ReadString(CS,'Back','Back');
Form1.goright.Hint:=SLS.ReadString(CS,'Forward','Forward');
REFLESHBTN_TEXT:=SLS.ReadString(CS,'Reflesh','Reflesh');
STOPBTN_TEXT:=SLS.ReadString(CS,'Stop','Stop');
//PAGE_POPUP SECTION LOAD
CS:='PAGE_POPUP';
Form1.ChromiumPopup.Items[0].Caption:=SLS.ReadString(CS,'Forward','Forward');
Form1.ChromiumPopup.Items[1].Caption:=SLS.ReadString(CS,'Back','Back');
Form1.ChromiumPopup.Items[2].Caption:=SLS.ReadString(CS,'Reflesh','Reflesh');
Form1.ChromiumPopup.Items[3].Caption:=SLS.ReadString(CS,'Copy_Link','Copy Link');
Form1.ChromiumPopup.Items[4].Caption:=SLS.ReadString(CS,'Save','Save');
Form1.ChromiumPopup.Items[5].Caption:=SLS.ReadString(CS,'Print','Print');
Form1.ChromiumPopup.Items[6].Caption:=SLS.ReadString(CS,'view_source','View Source');
Form1.ChromiumPopup.Items[7].Caption:=SLS.ReadString(CS,'code_debug','Code Debug');
End;
end.
Internal error means that the compiler itself is in a 'confused' state.
The way to get out of this is to:
Save your code in a safe location for later reference.
Restart Delphi
Revert the source code to the last known good state by undoing your last edits, or by loading a temp save file.
You can find the previous files in the _backup folder.
Make sure to set file type to any file.
In order to have Delphi generate a save file upon compilation you need to enable autosave
It's a good idea to have Delphi keep more than the default 10 saves. I like to set it to the max: 90.
Just keep restarting Delphi, and compile a previous version, until the internal error goes away.
Then you just recreate the code in a slightly different manner.
(You did save the original code right?)
I also had this problem (in Delphi 10 Berlin). It started shortly after I changed the name of a component in a frame. It also seemed very persistent. However I found the by right clicking the project and selecting 'Clean' followed by 'Build' solved the problem.
I had this issue with my system drive's memory less than 300mb left. It was especially choking in the cache folder. Prior to this error I had a sensible error (fatal error DBG) when I was attempting to recurse already async functions into a larger async function in a big multi threaded application. The compiler just gave up!(perhaps for circular references and too many subfunctions of a function) The two errors may not be related. But after freeing the system drive to about 2 Gigs upon restart and correcting the above mistake, I did a clean then it compiled just fine.
In my case, the solution for the F2084 error code was to change the encoding from ANSI to UTF8.
In my case, I made several packages that related one to another, and all were built as design and run time packages. But one day, I changed some of them to run-time only packages. After that I experienced this kind of error. It took me hours to realize that I should rebuilt all other related packages. After doing that, the error was away eventually.
Dear Stackoverflow users. I am in dire need for help. I have been struggling with the embedded in the Embarcadero XE2 RAD studio edition of FastReport 4.0. and more specifically I have been getting the same error, over and over again, which is the misterious "Class TfrxReport Not found" error. Below I submit a part of the code that causes the problems
procedure TForm1.buildReport(Sender: TObject);
var
DevicePic, SymbolPic: TfrxPictureView;
TitleEntry, xmlField: TfrxMemoView;
MasterDataBand: TfrxMasterData;
begin
if not ADOConnection1.Connected then
ShowMessage('Cannot build Report! Please, connect to the DB!')
else
try
//this is where the Class Not Found Exception is Thrown
frxReport1.LoadFromFile('LibreportTemplate.fr3',True);
// frxReport1.LoadFromFile('helloInfineonThree.fr3',True);
if (frxDBDataset1 = nil) then frxDBDataset1 := TfrxDBDataset.Create(Self);
// connect the report to the DATA
frxDBDataset1.DataSource := DataSource1;
frxReport1.DataSet := frxDBDataset1;
except
ShowMessage('Error has Occured! Report Template File Not Found!');
// exit from this procedure!
Exit;
end;
// If no errors have occured, go on building ur report by actually filling it up with data!
// attach dataSet to the masterdata band of the report.
MasterDataBand := frxReport1.FindObject('MasterData1') as TfrxMasterData;
MasterDataBand.DataSet := frxDBDataset1;
// prepare textfields
TitleEntry := frxReport1.FindObject('TitleEntry') as TfrxMemoView;
TitleEntry.DataSet := frxDBDataset1;
TitleEntry.DataField := 'LibFName';
xmlField := frxReport1.FindObject('xmlField') as TfrxMemoView;
// stretch the field if text too big.
xmlField.StretchMode := TfrxStretchMode.smActualHeight;
//get the XML DATA FROM THE DB.
xmlField.DataSet := frxDBDataset1;
xmlField.DataField := 'LibFXML';
// prepare images
DevicePic := frxReport1.FindObject('ImageEntry') as TfrxPictureView;
DevicePic.DataSet := frxDBDataset1;
DevicePic.DataField := 'LIBFIMAGE';
SymbolPic := frxReport1.FindObject('SymbolEntry') as TfrxPictureView;
SymbolPic.DataSet := frxDBDataset1;
SymbolPic.DataField := 'LibFSymbol';
// build and display report
frxReport1.PrepareReport();
frxReport1.ShowPreparedReport;
end;
When building and running the program, I get the following error message "Cannot Find class TfrxReport" and in DebugMode I get the following warning:
Project "MyProject.exe" raised exception class EClassNotFound with message 'Class TfrxReport not Found'.
As commented in the code above, the exception in question is thrown when executing the frxReport1.LoadFromFile('LibreportTemplate.fr3',True); command.
I tried many different approaches for solving the problem, including searching online for a solution. Here is what I did:
Manually create and destroy the frxReport1 object during Form OnCreate and OnClose - ERROR PERSISTS
As suggested in the FastReport ( I couldnt post the link on SO, cause of "Sorry, posts can't contain that content." error) forum thread, replace files in the FastReport 4\LibD16 folder. - ERROR PERSISTS
Recompile FastReport 4 RAD STUDIO 32 bit Version - ERROR PERSISTS
Recompile FastReport 4 RAD STUDIO 64 bit Version - ERROR PERSISTS
Reinstall Embarcadero RAD Studio and FastReport 4 - ERROR PERSISTS
ASK QUESTION IN STACKOVERFLOW - ????
From the thread in the fast-reports forum, it seems that the problem and the respective solution should be ( I QUOTE) :
This error causes by GroupDescendentsWith(TfrxReport, TControl); code.
This code hides TfrxReport from FierMonkey and for some reason
"FindClass" function can't find for TfrxReport class when you're
loading report(only in IDE). If you can't load report or get similar
error with "Couldn't find TfrxReport" message, put this "Link to Files"
files to "Fast
Report\LibD16" dir (replace all).
However the suggested approach DOES not Solve the problem! What should I do? Does anyone have any idea?
I've face this issue as well and I've solved it doing this,
Create a new ProjectGroup and add DPK's suitable for your delphi version (I use XE6).
You'll see the BPL's will divide into runtime and design.
Start compiling runtime fsX (X means version), fqbX, and so on. If you make a mistake in the order you will notice.
Some package need the search path $(BSDCOMMONDIR)/DCP to be added
Compile and install design packages and you'll see the TfrxReport.
You won't see results once design package is installed, I've restarted the IDE and it goes great ;)
With 2 years delay, I hope this could help!
not sure if you got your answer to this question or not... but I was having the same issue in Rad Studio XE4, using Fast Reports 4.0 Pro.
I had placed my report in a data module, which I could create / destroy when needed, and the datasets were found in there as well. I could place a BarCode element in the report designer, however, when running the application, I would get "Cannot find class TfrxBarCodeView".
After a search of the Source folder found in C:\Program Files (X86)\Fast Reports\source\ I opened a source file called frxBarcode.pas which contained the creation of the class "TfrxBarCodeView".
I simply added frxBarCode to my uses list, and all worked perfectly!
Just a thought.
Add RegisterClass(TfrxReport); somewhere on program's startup. Or, right before the line that raises the error.
I would start by
1
putting an absolute, full path to the fr3 file, and
place it in the user's document directory,
just to rule out file access issues. Do you have the source code to FastReport?
I know this is old but to somebody it might come useful.
I just run into similar problem. It never occurred to me there is a
component on the palette of Fast Reports called frxReportTableObject.
Just drop it on the form in question.
Adding frxBarCode to uses solved the problem.
I have the following code for executing a sql stored procedure that returns multiple resultsets, then reads this result from stream. For background info: it returns xml blocks as strings and then transforms it into complete xml.
It has worked well over a year but now i have a case that results in error message: Operation cancelled. Debugger shows: Project x raised exception class EOleException with message Operation cancelled.
I have no idea whats causing it. Any help or suggestions would be great.
const
adExecuteStream = $00000400; //Indicates that the results of a command execution should be returned as a stream.
var
objCmd, InputStream, XML, XSLT, Template, Processor, objConn, strmResults : Variant;
ATStreamClass : TMemoryStream;
Adapt : TStreamAdapter;
OutputStream: IStream;
objCmd := CreateOLEObject('ADODB.Command');
objCmd.ActiveConnection := dmABaasMock.dbRaAndm.ConnectionObject;
objCmd.CommandType := adCmdText;
objCmd.CommandText := <sp proc name with params>;
strmResults := CreateOLEObject('ADODB.Stream');
strmResults.Open;
objCmd.Properties['Output Stream'] := strmResults;
objCmd.Execute(EmptyParam, EmptyParam, adExecuteStream); // HERE COMES THE EXCEPTION
strmResults.Position := 0;
xmlMemo.text := strmResults.ReadText;
Difficult to guess what is going wrong without seeing more.
Three things you can do to get more debugging information:
What has changed between when it was working and now? OS version (or ADO), DB, stored proc,...
Is the stored proc working when launched directly in the SQL environment?
Could you rewrite your code to use the regular ADO components instead of doing late binding and get the results in DataSets instead of an ADODB.Stream OleObject. Only having Variant objects doesn't help much if you need to debug and drill down in the code? You can't debug a black box...
I recently had some strange error message when connecting to ADO, and not having the connection string right.
I'm not 100% sure it was the same error message (sorry, I forgot to take a screenshot back then), but if it is, then this might help:
In .NET, when you connect to ADO and use integrated security, you can specify Integrated Security="True", but using the native providers (not only in Delphi, but from any native environment), you will have to specify Integrated Security="SSPI".
I got into the situation because I was fiddling with connection strings (to connect from Delphi native win32 to a server that I previously connected to from .NET) and forgot to copy just the relevant parts.
--jeroen
I downloaded the Firebird DBX driver from http://sites.google.com/site/dbxfirebird/ and I've been able to compile the "Test Connection" project and get it to run. I pointed it to my test DB like so:
procedure TMainForm.Button1Click(Sender: TObject);
var C: TSQLConnection;
begin
C := TSQLConnection.Create(Self);
try
C.DriverName := 'FirebirdConnection';
C.Params.Add('User_Name=SYSDBA');
C.Params.Add('Password=masterkey');
C.Params.Add('Database=C:\fbtest\test.fdb');
C.Open;
if C.Connected then
ShowMessage('Connection is active')
finally
C.Free;
end;
end;
When I run it, it works fine. But when I put that exact same code in a different project, it doesn't work. I've copied the fbclient.dll (Firebird embedded driver DLL, renamed to fbclient), all of its dependencies, and the dbxdrivers.ini file to the same folder as the project's EXE is running in. I can't see any reason why this shouldn't work, but the call to .Open fails with:
Project Project1.exe raised exception
class TDBXError with message 'Unknown
driver: FirebirdConnection'.
Again, this is on the call to Open. The assignment to DriverName works just fine. Has anyone seen this problem before? Why does the exact same code work in the test project but not a different one, and is there any way I can fix it?
I found the problem. A loading class to set up the database driver had to be registered in the initialization section of DBXDynalink.pas. The test project included DBXDynalink in its uses clause, where mine didn't. I put that in and now it works.
This error generally occurs when you don't add the respective DBX driver unit to your uses list. Try adding DBXFirebird to your uses list.
Just change
C.DriverName := 'FirebirdConnection';
to
C.DriverName := 'Firebird';
and will work!