Solved

Using a VC++ dll in Delph - GPF?

Posted on 1999-01-26
3
235 Views
Last Modified: 2012-05-04
Hello guys.
I'm not sure whether this is a delphi or a VC problem, but I think it is a delphi one.
My setup is : A dll written in VC++, and a program written
in delphi, using it.
First I wrote one program, which used the dll, and it worked fine. Then I wrote ANOTHER program, which also used the same dll, and some of the functions worked great. But then I called one function, and got a General Protection error (this is the message:
'XBuilder caused an exception 10H in module <unknown> at
0000:00cc1f3b... etc'). XBuilder is my delphi app name'.
I tried to narrow the problem down. So I went to the declaration of the function, and made it empty (only remarks). THen I called it, same problem. I traced the problem with both the delphi and the VC++. The VC++ worked great, and the problem is AFTER the call to the function.
THe delphi works okay on the line calling the function, the bug starts on the NEXT line.
THen I tried to call other functions, and some worked great, some caused the same GPF.
I tried to check for c'tors or d'tors, or any code that might be invoked in the DLL, but The problem isn't there. It's as if the problem is within the delphi code. I just can't think of anything, because my OTHER delphi program, using the SAME dll works great!
what can I do?

Some more info:
1. I'm using delphi 3
2. Tried it on 2 computers, one running win98, and one running winNT, and it gets the same error on both.
3. I once had the same problem (In my buggy program). I called a function after pressing a speed button. I then moved from a speed button to a normal button, and the problem disappeared (!!!). I though 'okay, maybe delphi has some bug in speedbuttons'. But now I get the bug even if I call the function from my 'main'.
4. The declaration of the function in the dll looks like:

extern "C" void __cdecl FindX(int P, char *str)
{
      //
}

and the declaration in the DELPHI code looks like:

procedure FindX(P:Integer;str:Pchar);
stdcall; external DllLoc;

and the CALL from the delphi looks like this:
FindX(0,'shsh');

5. I searched for code in the new delphi application. I looked for initializtion parts on certain units, but the problem was not there.

--------------------------------------
So what do I do? How can I trace this problem? It suddenly happens with lots of functions from the dll. But only from my 'special' new delphi program! please help!!!
0
Comment
Question by:ShadowHawk071998
  • 2
3 Comments
 
LVL 12

Accepted Solution

by:
rwilson032697 earned 400 total points
ID: 1363417
ShadowHawk:

I think the problem is with this line (the calling conventions do not match...):

procedure FindX(P:Integer;str:Pchar);
    stdcall; external DllLoc;

it should read:

procedure FindX(P:Integer;str:Pchar);
    cdecl; external DllLoc;

Or you can change the function in the DLL to be __stdcall.

Cheers,

Raymond.
0
 

Author Comment

by:ShadowHawk071998
ID: 1363418
Hey, Thanks!
This actually worked, and worked great.
But I still wonder. How come it worked many times before (In my previous program, I used the same calls and it worked great) and only now it seemed to generate those GPF?
And I saw that it worked okay IN the C++ itself, but the bug was AFTER the call.
If you can shed some light on all this 'call' subject, I'd be very grateful.
Thanks!
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1363419
Calling conventions alter the way arguments are passed, and how stack frames are destroyed. Some conventions require the caller to clean up the stack, some require the called function to do it. Some of the interactions you get mean that the function calls OK, and does its job correctly, but either a failure to destroy a stack frame, or an attempt to destroy it twice can lead to nasty consequences.

I guess you were just lucky with your previous program!

Here's the clip from the Delphi help:

Cheers,

Raymond.



When you declare a procedure or function, you can specify a calling convention using one of the directives register, pascal, cdecl, stdcall, and safecall. For example,

function MyFunction(X, Y: Real): Real; cdecl;

 ...

Calling conventions determine the order in which parameters are passed to the routine. They also affect the removal of parameters from the stack, the use of registers for passing parameters, and error and exception handling. The default calling convention is register.

The register and pascal conventions pass parameters from left to right; that is, the leftmost parameter is evaluated and passed first and the rightmost parameter is evaluated and passed last. The cdecl, stdcall, and safecall conventions pass parameters from right to left.
      For all conventions except cdecl, the procedure or function removes parameters from the stack upon returning. With the cdecl convention, the caller removes parameters from the stack when the call returns.

The register convention uses up to three CPU registers to pass parameters, while the other conventions pass all parameters on the stack.
      The safecall convention implements COM error and exception handling.

The table below summarizes calling conventions.

Directive      Parameter order      Clean-up      Passes parameters in registers?
register      Left-to-right      Routine      Yes
pascal      Left-to-right      Routine      No
cdecl      Right-to-left      Caller      No
stdcall      Right-to-left      Routine      No
safecall      Right-to-left      Routine      No
The default register convention is the most efficient, since it usually avoids creation of a stack frame. The cdecl convention is useful when you call functions from DLLs written in C or C++, while stdcall and safecall are used for Windows API calls. The safecall convention must be used for declaring dual-interface methods. The pascal convention is maintained for backward compatibility. For more information on calling conventions, see Program control.

The directives near, far, and export refer to calling conventions in 16-bit Windows programming. They have no effect in 32-bit applications and are maintained for backward compatibility only.

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
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…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

747 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

13 Experts available now in Live!

Get 1:1 Help Now