Solved

Call pascal created DLL from Visual C++

Posted on 1998-02-25
13
590 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
Comment Utility
Answer coming.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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
Comment Utility
I simply can not pass compiling if I type

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

just because of that '__stdcall'.


0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Try

void (* __stdcall MYDLL)(BYTE *);

OR

void (__stdcall * MYDLL)(BYTE *);

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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
Comment Utility
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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 22

Expert Comment

by:nietod
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org (http://seleniumhq.org) Go to that link and select download selenium in the right hand columnThat will then direct you to their downlo…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

743 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now