We're doing a project at school (a small game), because most pupils in my class only program in pascal, we have a project with mixed C / Pascal. As a gfx library we use allegro. This mix worked great under djgpp, but we wanted some tcp/ip networking, so I tried to port things to cygwin. (I'll publish the gpc allegro wrapper I wrote after the project)
linking with windows gives some strange problems with global vars: A long description follows:
A typical line from allunit.pas is: var screen: BITMAP_ptr; asmname 'screen'; external; this produces a screen not found when linking the thing, however, linking the C files suceed. So I looked at the symbols with objdump -t -T, and saw that the C object files use __imp_screen instead of _screen, although C Declaration is also BITMAP *screen;
So I tried to changed the code to screen : BITMAP_ptr; asmname '_impl__screen'; external; which linked ok, but produced crashing progs. After some investigation, I discovered, that these __imp_screen, aren't the global var itself but a pointer to the var. This is bad, because it would mean to change all pascal files. C compiler seems to do this automagically.
Am I doing something wrong or can't gpc handle dll stuff right?
Matze
On 16 May 2001, at 15:29, Matthias Braun wrote:
[...]
A typical line from allunit.pas is: var screen: BITMAP_ptr; asmname 'screen'; external; this produces a screen not found when linking the thing, however, linking the C files suceed. So I looked at the symbols with objdump -t -T, and saw that the C object files use __imp_screen instead of _screen, although C Declaration is also BITMAP *screen;
So I tried to changed the code to screen : BITMAP_ptr; asmname '_impl__screen'; external; which linked ok, but produced crashing progs. After some investigation, I discovered, that these __imp_screen, aren't the global var itself but a pointer to the var.
Yes. Isn't that what the "*" in the declaration means?
This is bad, because it would mean to change all pascal files. C compiler seems to do this automagically.
Nothing is automatic. It all depends on how the variables were used in the C code.
Am I doing something wrong or can't gpc handle dll stuff right?
GPC can handle dll stuff quite fine. The entire Win32 API is dll-based, and GPC programs can use the API with no problem. You need to make sure that you are dereferencing the pointers where appropriate. But may also need to attach the "stdcall" attribute to the DLL function imports. What I do to simply it all is this;
{$define Stdcall attribute(stdcall)} {$define WINAPI(X) asmname X; Stdcall} FUNCTION GetDC ( Wnd : HWND ) : HDC; WINAPI ( 'GetDC' ); blah, blah ....
This all presupposes of course that the DLL functions are exported as STDCALL (which they normally should).
Best regards, The Chief --------- Prof. Abimbola Olowofoyeku (The African Chief) Author of Chief's Installer Pro for Win32 Email: African_Chief@bigfoot.com http://www.bigfoot.com/~african_chief/
Matthias Braun wrote:
A typical line from allunit.pas is: var screen: BITMAP_ptr; asmname 'screen'; external; this produces a screen not found when linking the thing, however, linking the C files suceed. So I looked at the symbols with objdump -t -T, and saw that the C object files use __imp_screen instead of _screen, although C Declaration is also BITMAP *screen;
So I tried to changed the code to screen : BITMAP_ptr; asmname '_impl__screen'; external; which linked ok, but produced crashing progs. After some investigation, I discovered, that these __imp_screen, aren't the global var itself but a pointer to the var.
You mean a pointer to a pointer (because you already declared it as a pointer)?
Perhaps C uses some #defines in a header like: #define screen (*_impl__screen)
So you can replace screen by _impl__screen^ in the Pascal files, or you write access routines in C for which you provide a Pascal interface. The advantages are, the C routine use the headers and therefore all the macros the library uses (even if they change it in future versions or on different platforms), and you know the header of your C routines, therefore you can write a matching Pascal interface (also independent on any strangeness the library does).
Frank