problem using delphi dll in vc++

R

Ryanivanka

hi,
I am using a delphi DLL in vc++,static linked with ".h"and "lib".
the export functions in DLL are "__stdcall",but the function doesn't
work well,it often returns some weird values.
when I add codes as follows,it suddenly works well. why??

DWORD returnAdd;
__asm
{
mov ecx,[ebp+4]
mov returnAdd, ecx
}

I am confused,if there is something wrong with stack,I have already
using "__stdcall",why it is still wrong?
I don't even know what those asm code do,I just add them to get some
status about stack.what else they do to the program that I don't know?

thank you .
Ryan
 
C

Cholo Lennon

Ryanivanka said:
hi,
I am using a delphi DLL in vc++,static linked with ".h"and "lib".
the export functions in DLL are "__stdcall",but the function doesn't
work well,it often returns some weird values.
when I add codes as follows,it suddenly works well. why??

DWORD returnAdd;
__asm
{
mov ecx,[ebp+4]
mov returnAdd, ecx
}

I am confused,if there is something wrong with stack,I have already
using "__stdcall",why it is still wrong?
I don't even know what those asm code do,I just add them to get some
status about stack.what else they do to the program that I don't know?

It's seems to be a calling convention problem.
I understad that you are using __stdcall in C++ code. Do you use 'stdcall'
modifier in Delphi functions?
Where do you add the asm code? (Before or after a DLL calling?)
Does Delphi compiler generate the import .lib file? or do you obtain it with
some tool?
 
R

Ryanivanka

hi,Cholo
thank you for your time. :)

yes ,the "stdcall" is also used in that delphi ".h".
the".lib" which I download free version might be compiled in Delphi
environment.

those asm code was put in front of a function (named A()) which
doesn't work well until the asm codes were added. and it's long after
the delphi dll is loaded(before that function ,lots of function from
dll have already been correctly used ).

and the implementation troubled function A() has something to do with
asm,because it read information from calling stack.

so I wonder if compiler make that call using "fastcall" not
"stdcall",and the registers and stack were wrong. but,as I said before
"stdcall" is used in its ".h". Is that enough to convert a delphi
calling convention to a c++ way? or what I should do to convert
".h",".lib" or".dll"?

thank you.

regards,
Ryan



"Ryanivanka" <[email protected]> escribi¨® en el mensaje

hi,
I am using a delphi DLL in vc++,static linked with ".h"and "lib".
the export functions in DLL are "__stdcall",but the function doesn't
work well,it often returns some weird values.
when I add codes as follows,it suddenly works well. why??
DWORD returnAdd;
__asm
{
mov ecx,[ebp+4]
mov returnAdd, ecx
}
I am confused,if there is something wrong with stack,I have already
using "__stdcall",why it is still wrong?
I don't even know what those asm code do,I just add them to get some
status about stack.what else they do to the program that I don't know?

It's seems to be a calling convention problem.
I understad that you are using __stdcall in C++ code. Do you use 'stdcall'
modifier in Delphi functions?
Where do you add the asm code? (Before or after a DLL calling?)
Does Delphi compiler generate the import .lib file? or do you obtain it with
some tool?
 
C

Cholo Lennon

Ryanivanka said:
hi,Cholo
thank you for your time. :)

yes ,the "stdcall" is also used in that delphi ".h".
the".lib" which I download free version might be compiled in Delphi
environment.


those asm code was put in front of a function (named A()) which
doesn't work well until the asm codes were added. and it's long after
the delphi dll is loaded(before that function ,lots of function from
dll have already been correctly used ).

and the implementation troubled function A() has something to do with
asm,because it read information from calling stack.

so I wonder if compiler make that call using "fastcall" not
"stdcall",and the registers and stack were wrong. but,as I said before
"stdcall" is used in its ".h". Is that enough to convert a delphi
calling convention to a c++ way? or what I should do to convert
".h",".lib" or".dll"?

You can't convert Delphi calling convention from C++. You have to define the
same calling convention on both sides (Delphi and C++). Be warned that ms
fastcall is distinct to borland fastcall
(http://en.wikipedia.org/wiki/X86_calling_conventions)

Can you show us the function prototype? (delphi & C++). Also would be
interesting to see how VC++ generate the calling (with and without the asm
code). Use the dissasembly window to cut the code.

BTW, Which versions of VC and Delphi are you using?
 
T

Tamas Demjen

Ryanivanka said:
so I wonder if compiler make that call using "fastcall" not
"stdcall",and the registers and stack were wrong. but,as I said before
"stdcall" is used in its ".h". Is that enough to convert a delphi
calling convention to a c++ way? or what I should do to convert
".h",".lib" or".dll"?

In a function call both sides have to agree about the "protocol"
details. It's not enough to add __stdcall to the .h file, you also have
to do it on the Delphi side. For example,

procedure SayHi; stdcall;
begin
ShowMessage("Hi");
end;

This would be declared as void __stdcall SayHi(); in the .h file. If you
miss the stdcall from either side, it won't work. Optionally, you could
use cdecl on both sides, Delphi can handle that. As Cholo said, don't
use fastcall, it's not compatible across compilers.

In addition to making the calling conventions compatible, you also have
to make sure that the argument sizes and alignments match. For example,
Borland's enumerations have the size of 1 byte by default, while in VC++
an enum is treated as an integer (4 bytes). String arguments must be
passed as PChar/char*. Some Delphi floating point types aren't
compatible with VC++ floating point types. Delphi functions are able to
return types not allowed in C/C++ (such as arrays). If you allocate
memory in Delphi, you must delete it from Delphi, too.

I think you should show us your C and Delphi declarations, and we should
be able to compare them for you.

Delphi classes must be flattened into C-style functions before you can
use them from VC++, or they can be wrapped into COM objects.

Tom
 
R

Ryanivanka

hi,

you two both asked about the prototype in delphi and c++,they are as
follows.
------------------------in c++ .h-------------------------
extern "C" {
__declspec(dllimport) HMODULE __stdcall func1();
}
------------------------------------------------------------

-----------------------in delphi-----------------------------
function func1: dword; stdcall;
----------------------------------------------------------------

and I can't change anything about the delphi dll,but I thought it's in
right prototype in delphi,right?

in c++, I just use the function as " HMODULE hmod=func1();",then the
answer is wrong ,but the stack is ok(the function could return to
right place).

with the asm codes,
------------------------------------------
DWORD returnAdd;
__asm
{
mov ecx,[ebp+4]
mov returnAdd, ecx
}
-----------------------------------------
it change the register "ecx" value,then the func1() would works well.
and the implementation of fun1() in delphi might be inline asm too.(I
expect that because the function is reading stack values and I don't
know if it use any register.)

and I am not sure the version of delphi,but I use VS.net as the C++
IDE. If I call the delphi dll in a MFC program,would that be something
different?

should I disassemble the delphi dll to get some details?

thank you all,

regards,
Ryan
 
T

Tamas Demjen

Ryanivanka said:
------------------------in c++ .h-------------------------
extern "C" {
__declspec(dllimport) HMODULE __stdcall func1();
}
------------------------------------------------------------

-----------------------in delphi-----------------------------
function func1: dword; stdcall;
----------------------------------------------------------------

They look compatible.

I just don't understand how you were able to link a Delphi DLL
statically. Borland/CodeGear uses OMF-type LIB files, VC++ uses the COFF
format. They're not compatible. Not even for simple import libraries.

So you either have a bug in the Delphi function, or in the import
library. I recommend that you forget about that LIB, and just load the
DLL dynamically:

HINSTANCE dll = LoadLibrary("c:\\path\\to\\my.dll");
typedef HMODULE (__stdcall * PtrFunc1)();
PtrFunc1 func1 =
reinterpret_cast<PtrFunc1>(GetProcAddress(dll, "func1"));
....
// use func1 as if it was a regular C function
....
FreeLibrary(dll);

Of course you have to use GetProcAddress for all the other functions
that the DLL might export as well. It may be a little bit of an extra
work (lots of typing), but you can be 100% sure that the functions are
imported correctly.

I just don't know where your LIB file is coming from, it can't be coming
from Delphi. LIB and OBJ files are generally not portable enough.

Tom
 
R

Ryanivanka

thank you all.....I found out there are something wrong about the
function.
So I just want to realize it by myself.Thank you all.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top