?
Solved

Handling Exception from DLL

Posted on 2000-03-11
20
Medium Priority
?
1,628 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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
 
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 400 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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses
Course of the Month10 days, 20 hours left to enroll

770 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