Solved

Using a VC++ dll in Delph - GPF?

Posted on 1999-01-26
3
243 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
[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
  • 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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

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…
If you're a developer or IT admin, you’re probably tasked with managing multiple websites, servers, applications, and levels of security on a daily basis. While this can be extremely time consuming, it can also be frustrating when systems aren't wor…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…

726 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