Solved

Call pascal created DLL from Visual C++

Posted on 1998-02-25
13
624 Views
Last Modified: 2013-12-14
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
0
Comment
Question by:cw43
13 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 1182836
Answer coming.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1182837
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
 

Author Comment

by:cw43
ID: 1182838
I simply can not pass compiling if I type

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

just because of that '__stdcall'.


0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:nietod
ID: 1182839
Try

void (* __stdcall MYDLL)(BYTE *);

OR

void (__stdcall * MYDLL)(BYTE *);

0
 
LVL 22

Expert Comment

by:nietod
ID: 1182840
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
 
LVL 1

Expert Comment

by:rayofunreal
ID: 1182841
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
 
LVL 22

Expert Comment

by:nietod
ID: 1182842
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
 
LVL 5

Expert Comment

by:inter
ID: 1182843
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
 
LVL 22

Expert Comment

by:nietod
ID: 1182844
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
 
LVL 5

Expert Comment

by:inter
ID: 1182845
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
 
LVL 22

Expert Comment

by:nietod
ID: 1182846
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
 
LVL 5

Expert Comment

by:inter
ID: 1182847
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
 
LVL 1

Accepted Solution

by:
spap earned 100 total points
ID: 1182848
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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Setting nameservers after res_init fails doing res_query 2 120
How to gracefully close the c++ 11 thread? 3 123
Add values of each row in an array 3 71
visual C++ 1 15
When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

730 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