🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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
#2844
Author: Renald Yazmir
Date: Fri, 01 Dec 2006 14:08
81 lines
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
#2847
Author: Remy Lebeau (TeamB)
Date: Fri, 01 Dec 2006 18:11
68 lines
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