Handling Exception from DLL

An Exception is raised from a DLL, in my main program I write a global Exception handler link the following:

TMainForm.OnAppException(Sender: TObject; E: Exception);
begin
  ShowMessage(E.Message);
end;

I assign it to Application.OnException event. But this handler wasn't called when an exception raising. I check the Application.HandleException definition in Forms unit, and I found that the HandleException procedure didn't call the FOnException event, it directlly went to line
  SysUtils.ShowException(ExceptObject, ExceptAddr)

Any help?
smartkidAsked:
Who is Participating?
 
rwilson032697Commented:
You could try giving the DLL you application instance by having a function in the DLL like this:

var
  OldApp : TApplication;

procedure SetApplication(Appl : TApplication);
begin
  OldApp := Appl;
  Application := Appl;
end;

procedure UnSetApplication;
begin
  Application := OldAppl;
end;

Call SetApplication with the Application from the main program. CAll UnSetApplication before you unload the DLL or you will get nasty exceptions :-)

Cheers,

Raymond.
0
 
rwilson032697Commented:
Try building the app and dll with runtime packages enabled (go to Project|Options, Packages and check 'Build with runtime packages')

Do this for both the DLL and the app.

Cheers,

Raymond.
0
 
smartkidAuthor Commented:
I tried to compile the DLL with using runtime packages but failed with an error message:
  Required package 'dcctd5' not found

In that DLL I only use DOA to establish a connection to oracle database. I check my package list in Project/Package but can not find a package named dcctd5.

Have you heared of this package?
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
smartkidAuthor Commented:
With the following way I can catch the exception message correctly:

SomeProcInMain;
begin
  try
    CallDLLFunc;
  except
    on E : Exception do
      ShowMessage(E.Message);
end;

But when I use the Application.OnException, only the address of the Exception showed, not the message of the exception which I want.

By the way, I am using Delphi 5 with Update Pack 1.
0
 
MadshiCommented:
smartkid, there are two possibilites for you:

(1)

try
  CallDLLFunc;
except
  ShowException(ExceptObject, ExceptAddr);
end;

(2)

procedure ExceptHandler(ExceptObject: TObject; ExceptAddr: Pointer); far;
begin
  ShowException(ExceptObject, ExceptAddr);
  Halt(1);
end;

initialization
  ExceptProc := @ExceptHandler;
end.

Regards, Madshi.
0
 
MadshiCommented:
P.S: If you want to know how to get the exception text from ExceptObject, look at the VCL sources for ShowException. It's in SysUtils.pas I think.
0
 
smartkidAuthor Commented:
Sorry, still not work.

I still got the exception address shown but not the exception message.

0
 
smartkidAuthor Commented:
Very strange things:

  try
    CallDLLProc;
  except
        on E : Exception do
    begin
          ShowMessage('E.ClassName -> ' + E.ClassName);
              ShowMessage('E.Message -> ' + E.Message);
      ShowMessage('ExceptObject.ClassName -> ' + ExceptObject.ClassName);
      if ExceptObject is Exception then
            ShowMessage('ExceptObject is an Exception') else
            ShowMessage('ExceptObject is not an Exception');
      raise;
    end;
  end;


The messages are shown:
1)  E.ClassName -> EOracleError (an Exception defined in DirectOracleAccess as EOracleError=class(Exception))
2)  E.Message -> ORA-00942 : XXXXX
3)  ExceptObject.ClassName -> EOracleError
4) ExceptObject is not an Exception

0
 
smartkidAuthor Commented:
Adjusted points to 100
0
 
MadshiCommented:
So what now? Originally you said, you don't get the exception message text. But now you say you get it?

I can't tell you why ExceptObject is not an Exception, but does that matter? Well, I guess, it's because the DLL has its own copy of the VCL, so the Exception object class of the DLL is not the same class as that of your application. So "ExceptObject is Exception" fails, because ExceptObject is the reference to the DLL Exception class, while "is Exception" tests, whether ExceptObject is a reference to the application Exception class. Aht least that's what I guess...
0
 
smartkidAuthor Commented:
I mean I cannot handle the exception with showing the exception's original message in a central position as Application.OnException or somewhere else.

Till now, I can just get the original message immediate after the CallDllProc.
0
 
MadshiCommented:
And you have tried setting ExceptProc like I've suggested in my answer part (2) with ExceptProc?
0
 
rwilson032697Commented:
Smartkid: Do you know what dcctd5 is?

Using runtime packages will fix it for you, I am fairly sure!

Cheers,

Raymond.
0
 
smartkidAuthor Commented:
To Madshi:
   Yes, I've already set the ExceptProc like you suggested.

To rwilson:
  I don't know what dcctd5 is. It seems like a runtime package, but I cannot find it, neither in my computer or others in my company.
0
 
rwilson032697Commented:
Do you have "Include TD32 Debug Info" checked in Project|Options -> Linker?

Something must require it...

Cheers,

Raymond.
0
 
rwilson032697Commented:
Just did a complete search on my machine for dcct5 with no luck. Perhaps it is a third party component you are using?
0
 
MadshiCommented:
Strange thing... If you don't get along with Raymond's package suggestion, I've another suggestion we could try. I've written an exception handler Delphi component, which does much more than Delphi's exception handling, e.g. call stack tracing. If you are interested, I could send you some DCUs (no sources for now, sorry). You could try then, whether my component can get the exception message. If not:  :-((  If yes: You can use the DCUs for now and perhaps later (if you want) buy the sources, when the components are finished and published.
However, you need either D4 or D5. Tell me your version and your eMail-address, if you're interested.

Regards, Madshi.
0
 
smartkidAuthor Commented:
to rwilson:
  I use DOA in my project, but that only require doa.bpl.

Regards, smartkid.

to madshi:

  My application must be finished in the next week, so may be there is no enough time to wait for your final version, my boss urges me day and night :-(((

  The other important problem is that I am a Chinese and it very hard to buy a component through internet or check.

  I hope if you can send me some lines of source just to make my app running after I get succeed with your DCUs. If you wish, I can send you some postcard for interchange :-).

  my email is smartkid@nari-china.com
  I am using Delphi 5 enterprise version with Update Pack 1.

with best wishes.
smartkid
0
 
MadshiCommented:
What shall I say? You can of course test my components, but you're not allowed to use them in the final product (if it's commercial) without paying...  :-(  Testing my components might help though finding the real problem. Still interested? Then I'll mail you the DCUs. I hope Delphi5withoutUpdatePack-DCUs work, too, because the german update pack is not ready yet...

Regards, Madshi.
0
 
rwilson032697Commented:
Something else to check: Make sure dcctd5 isn't listed in the list of package names under the "Build with runtime packages" option...

Cheers,

Raymond.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.