Call pascal created DLL from Visual C++

I have created a DLL by Pascal compiler with a function which takes a pointer to a BYTE array as an argument.  My Visual C++ application will also take this BYTE array as output after I call this Pascal function in that DLL.  However, the output simply is not correct.  The way I load the DLL is like:

extern "C"{
    typedef void (*MYDLL)(BYTE *);
    MYDLL myDll;
}

And then I use LoadLibrary() to load DLL and use GetProcAddress() to get a pointer to myDll() in DLL.  However, it simply gave me wrong answers (it works fine if I load that DLL from a Pascal application).  So my question is: is there any other things that I need to worry about when I load this DLL because of mixing language issue?

Thanks,

Richard
cw43Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

nietodCommented:
Answer coming.
0
nietodCommented:
I assume first of all that GetProcAddress() is ruturning a non-NULL pointer?  right?  

First of all you need to consider calling conventions.  By default C++ will push parameters onto the stack from right to left.  The caller is responsible for cleaning up the stack after the function returns.  That is probably not the way Pascal works by default.  Pascal probably pushes from parameters from left to right and the function probably cleans up the stack before it returns.  You should try to verify this in your manuals.  Look under "calling conventions".  
To get them to cooperate you need to get C++ or Pascal to use the other calling convention.  

To get C++ to let the function clean up the stack you can use the __stdcall declaration.  For example

 typedef void __stdcall (*MYDLL)(BYTE *);

This will probably still pass the arguments in the wrong order.  Since there is one, no big deal.  If you have multiple arguments, you will have to reverse their order in C++.  

An other approach would be to change it on the pascal side.  I'm not sure of those details.

If this does not help, see if you can find something about the pascal callign convention.

Another area of concern is that pascal and C++ might pack arrays differently.  But this probably is not the problem.
0
cw43Author Commented:
I simply can not pass compiling if I type

'typedef void __stdcall (*MYDLL)(BYTE*);'

just because of that '__stdcall'.


0
Starting with Angular 5

Learn the essential features and functions of the popular JavaScript framework for building mobile, desktop and web applications.

nietodCommented:
Try

void (* __stdcall MYDLL)(BYTE *);

OR

void (__stdcall * MYDLL)(BYTE *);

0
nietodCommented:
Note this is kinda unnecessary.  You do not have to use explicit linking (LoadLibrary() and GetProcAddress() in order to get c++ to call pascal.  You can simply declare the function as _declspec(dllimport) and call it normally.  (Unless there is another reason you are using explicit linking.)
0
rayofunrealCommented:
Try tu use some parameter modificator (depend on your's pascal and visual compiler) such as REGISTER caling convections. When I need to use PASCAL dll with WATCOM I don't have to write calling convetions, because WATCOM uses REGISTER. With borland I have to wrote REGISTER.
0
nietodCommented:
That's unusual, I've never heard of a Pascal that passes parameters in registers by default.  The C++ __fascall (instead of __stdcall) passes parameters in registers.  However, I think we need to find out pascal's calling convention.  Did you find anything in the docs?
0
interCommented:
Dear nietod,

Delphi 2.0+ does register calling convention by default (if we call it as pascal).

Dear cw43,

What pascal compliler you use?
If Delphi you may 4 alternative try exporting by(i.e. modify pascal code not C code):

pascal
stdcall
cdecl
register

One should work
Igor
0
nietodCommented:
Your best bet might be to make the pascal function cdecl and then leave the C code alone.  I don't know the procedure for doing so, however.  
0
interCommented:
Reminder,

In win31 or wow16 subsystem on winNt or win95 the default calling convention for dlls are PASCAL. In Win32 it is stdcall, this is due to the proglog and epilog (these are opcodes for pushing and poping segments and preparing stack) imposed by windows.

So if your applications are 16 bit, then you -as far as I know- should use pascal, else stdcall. But I never tried cdecl, may be it is right.

Regards,
Igor
0
nietodCommented:
What you are referring to is the calling convention for the system Dll's, that is Kernal, GDI, User, etc.  This has no bearing on the calling convention used on Dll's created by a particular language.  
0
interCommented:
You are right, however it is good programming practice -in my opinion- fow win32. So times, you may want to bind your functions to API-so the win32 should call them- so why not...

Anyway are you there cw43?
Igor
0
spapCommented:
Supposing the dll is already created, try the folowing code:

///////
typedef BYTE* (CALLBACK *MYDLLFUN)(BYTE*);
MYDLLFUN myf;
   

HINSTANCE hib=LoadLibrary("path_to_dll\\mydll.dll");assert(hlib!=NULL);
myf=(MYDLLFUN)GetProcAddress(hLib,"function_name");assert(myf!=NULL);

//test using the folowing

BYTE *input_array=new BYTE[25];

BYTE *out_arr=(*myf)(input_array);
assert(FreeLibrary(hLib));
////////////
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.