Solved

Handling Exception from DLL

Posted on 2000-03-11
20
1,546 Views
Last Modified: 2007-10-18
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?
0
Comment
Question by:smartkid
  • 8
  • 6
  • 6
20 Comments
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2607410
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
 

Author Comment

by:smartkid
ID: 2607431
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
 

Author Comment

by:smartkid
ID: 2607439
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
 
LVL 20

Expert Comment

by:Madshi
ID: 2607466
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
 
LVL 20

Expert Comment

by:Madshi
ID: 2607468
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
 

Author Comment

by:smartkid
ID: 2607515
Sorry, still not work.

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

0
 

Author Comment

by:smartkid
ID: 2607523
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
 

Author Comment

by:smartkid
ID: 2607529
Adjusted points to 100
0
 
LVL 20

Expert Comment

by:Madshi
ID: 2607569
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
 

Author Comment

by:smartkid
ID: 2607626
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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 20

Expert Comment

by:Madshi
ID: 2607684
And you have tried setting ExceptProc like I've suggested in my answer part (2) with ExceptProc?
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2608338
Smartkid: Do you know what dcctd5 is?

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

Cheers,

Raymond.
0
 

Author Comment

by:smartkid
ID: 2609071
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
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2609076
Do you have "Include TD32 Debug Info" checked in Project|Options -> Linker?

Something must require it...

Cheers,

Raymond.
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2609106
Just did a complete search on my machine for dcct5 with no luck. Perhaps it is a third party component you are using?
0
 
LVL 20

Expert Comment

by:Madshi
ID: 2609118
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
 

Author Comment

by:smartkid
ID: 2609467
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
 
LVL 20

Expert Comment

by:Madshi
ID: 2609754
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
 
LVL 12

Accepted Solution

by:
rwilson032697 earned 100 total points
ID: 2610160
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
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2610163
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

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now