Thread View: borland.public.cppbuilder.nativeapi
2 messages
2 total messages
Started by Renald Yazmir
Fri, 01 Dec 2006 14:08
Calling Pascal and C dll from the same application
Author: Renald Yazmir
Date: Fri, 01 Dec 2006 14:08
Date: Fri, 01 Dec 2006 14:08
81 lines
2716 bytes
2716 bytes
I have C application that calls Pascal dll written in Delphi 4
Here is the function in C application that calls a function in Pascal
dynamically:
double do_something(void)
{
double a;
typedef double FAR PASCAL (* p)(void);
p fun_name;
fun_name = (p)GetProcAddress(hLib, "do_something_in_dll");
if(fun_name != NULL)
a = (fun_name)();
return a;
}
I converted Pascal dll into C.
In dll I declare export function:
extern "C" double __declspec(dllexport) do_something_in_dll(void);
In my calling appication I kill "FAR PASCAL "
double do_something(void)
{
double a;
typedef double (* p)(void);
p fun_name;
fun_name = (p)GetProcAddress(hLib, "do_something_in_dll");
if(fun_name != NULL)
a = (fun_name)();
return a;
}
Works fine!!!
----------------------------------------------
My goal now is to be able to use both Pascal and C dlls with the same
calling application.
Therefore I want to preserve old style calling convention with FAR PASCAL:
double do_something(void)
{
double a;
typedef double FAR PASCAL (* p)(void);
p fun_name;
fun_name = (p)GetProcAddress(hLib, "do_something_in_dll");
if(fun_name != NULL)
a = (fun_name)();
return a;
}
My question is how can I declare a function in the C dll with FAR PASCAL so
it can be compatible
with "my old style" calling convention.
I tried def file. It did not work.
Here is what I did in dll:
in def:
LIBRARY my_new_c_dll
EXPORTS
do_something_in_dll
in c:
double FAR PASCAL do_something_in_dll(void)
{
.....
}
in h:
double FAR PASCAL do_something_in_dll(void);
Thank you.
Renald
Re: Calling Pascal and C dll from the same application
Author: Remy Lebeau (TeamB)
Date: Fri, 01 Dec 2006 18:11
Date: Fri, 01 Dec 2006 18:11
68 lines
3255 bytes
3255 bytes
"Renald Yazmir" <renald@partmaker.com> wrote in message
news:4570372f$1@newsgroups.borland.com...
> double a;
You are not initializing the variable. If the DLL function fails to load,
you will be returning a random value back to the caller of your C function.
> typedef double FAR PASCAL (* p)(void);
You should always write your DLLs to export functions using the __stdcall
calling convention. That is the only calling convention that is supported
across multiple programming languages equally. Delphi and C++Builder both
support __stdcall. Despite its name, the PASCAL macro (which resolves to
__pascal) is *not* the same calling convention that Delphi actually uses!
Delphi uses __fastcall instead by default. So if you do not declare any
calling convention in the Delphi code, your DLL function will be exported
using __fastcall, but your C code is then using __pascal instead. The two
are not compatible.
> In dll I declare export function:
> extern "C" double __declspec(dllexport) do_something_in_dll(void);
Use the __stdcall calling convention:
extern "C" double __declspec(dllexport) __stdcall
do_something_in_dll(void);
> In my calling appication I kill "FAR PASCAL "
You should not kill the call convention altogether. Simply replace PASCAL
with WINAPI (or __stdcall directly):
double do_something(void)
{
double a = 0.0;
typedef double __stdcall (* p)(void);
p fun_name;
fun_name = (p)GetProcAddress(hLib, "do_something_in_dll");
if(fun_name != NULL)
a = (fun_name)();
return a;
}
> Works fine!!!
As it should be. When you wrote the DLL in C, the calling conventions used
in both the DLL and the application matched. That was not the case when you
wrote the DLL in Delphi. Calling conventions must always match in order to
work properly.
> My goal now is to be able to use both Pascal and C dlls with the same
> calling application.
You have to write your Pascal DLLs in such a way that they are compatible
with other languages.
> Therefore I want to preserve old style calling convention with FAR PASCAL:
That is the wrong thing to do. You need to use __stdcall instead if you
want your Delphi DLLs to be usable in non-Pascal environments.
Gambit
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads