Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2010-03

-Twin32 linker woes

10 messages · 5 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Adriaan van Os

I am cross compiling with fpc svn trunk and -Twin32 on i386 Mac OS X to Win32. This works fine, except that {$linklib xxx.dll} says

error: 1: Import library not found for xxx

Same result with {$linklib xxx}. The dll (and dll.lib) are absolutely there, {$linklib xxx.dll.lib} says

error: 8: Invalid DLL xxx.dll.lib, Dos Header invalid

I tried several dll's, all with the same result. Next, I built and installed mingw binutils-2.20 (--target=i686-pc-mingw32 --host=i686-apple-darwin8 --build=i686-apple-darwin8 --prefix=/usr/local) to link external (without the {$linklib}) and got

ld warning: option -b is obsolete and being ignored ld: file not found: pe-i386

Well, one solution is to link at runtime, but I am grateful for hints at what can be wrong (the same dll links fine with another compiler).

Regards,

Adriaan van Os

Marco van de Voort
to Adriaan van Os

In our previous episode, Adriaan van Os said:

I am cross compiling with fpc svn trunk and -Twin32 on i386 Mac OS X to Win32. This works fine, except that {$linklib xxx.dll} says

dlls are usually not $linklib'ed in FPC. What happens if you simply omit the linklib?

Adriaan van Os
to Marco van de Voort: In our previous episode, Adriaan van Os said: dlls are usually not $linklib'ed in FPC.…
Marco van de Voort wrote 6 lines
In our previous episode, Adriaan van Os said: > I am cross compiling with fpc svn trunk and -Twin32 on i386 Mac OS X to Win32. This works fine, > except that {$linklib xxx.dll} says dlls are usually not $linklib'ed in FPC. What happens if you simply omit the linklib?

Well, then the linker complains about unresolved symbols.

Does that mean that LoadLibrary and GetProcAddress must be called for all external dll calls ?

Anyway, the "not found" message is confusing. I suggest a clarification in the section about
{$linklib} in the Free Pascal Programmer’s Guide that only static libraries can be linked.

Thanks for your reply.

Regards,

Adriaan van Os

Jonas Maebe
to Adriaan van Os
Adriaan van Os wrote 9 lines
Marco van de Voort wrote: > In our previous episode, Adriaan van Os said: >> I am cross compiling with fpc svn trunk and -Twin32 on i386 Mac OS >> X to Win32. This works fine, except that {$linklib xxx.dll} says > dlls are usually not $linklib'ed in FPC. What happens if you simply > omit the > linklib? Well, then the linker complains about unresolved symbols.

You have to mention the name of the dll in the procedure declaration:

procedure test; stdcall; external 'dllname';
Does that mean that LoadLibrary and GetProcAddress must be called for all external dll calls ?

No.

Anyway, the "not found" message is confusing. I suggest a clarification in the section about {$linklib} in the Free Pascal Programmer’s Guide that only static libraries can be linked.

That only applies to Windows.

Jonas

Tomas Hajny
to Adriaan van Os: Well, then the linker complains about unresolved symbols. Does that mean that LoadLibrary…
Adriaan van Os wrote 14 lines
Marco van de Voort wrote: > In our previous episode, Adriaan van Os said: >> I am cross compiling with fpc svn trunk and -Twin32 on i386 Mac OS X to >> Win32. This works fine, >> except that {$linklib xxx.dll} says > > dlls are usually not $linklib'ed in FPC. What happens if you simply omit > the > linklib? Well, then the linker complains about unresolved symbols. Does that mean that LoadLibrary and GetProcAddress must be called for all external dll calls ?

No, certainly not. Normally, something like the following would be used:

function FreeLibrary (hLibModule:HINST):WINBOOL; external 'kernel32' name
'FreeLibrary';

I.e. function FreeLibrary is imported from kernel32.dll. Note that in this case the declaration also includes information on the external name; I believe that a mangled (or at least uppercase) name would be expected otherwise (at least in the past the expected mangled name depended on the specified calling convention in FPC - as opposed to some other compilers which allow specifying mangling independently from calling conventions). Note that this doesn't work for the OS/2 target (my primary domain) because functions are usually imported from dynamic libraries by their ordinal numbers there (which is also why I don't know the details for WinXX for sure except that the above works).

Another alternative (common with some compilers for OS/2, but usually not used with FPC) might be using an explicitly generated import library. Such an import library is just a static library containing "translation" of symbols defined as externals in the pascal source code to invocation of the respective dynamic library routines. If you do this, you need to make sure that the names defined in the import library match those expected by the compiler for the external symbol (i.e. that there isn't some/different mangling in place). I believe that you tried doing this in one of your attempts (but I may be wrong there).

Tomas

Tomas Hajny
to Jonas Maebe: You have to mention the name of the dll in the procedure declaration: procedure test;…
Jonas Maebe wrote 8 lines
On 11 Mar 2010, at 12:28, Adriaan van Os wrote: > Marco van de Voort wrote: >> In our previous episode, Adriaan van Os said: >>> I am cross compiling with fpc svn trunk and -Twin32 on i386 Mac OS >>> X to Win32. This works fine, except that {$linklib xxx.dll} says >> dlls are usually not $linklib'ed in FPC. What happens if you simply >> omit the >> linklib?

.
.

Show quoted text 5 lines
> Anyway, the "not found" message is confusing. I suggest a > clarification in the section about {$linklib} in the Free Pascal > Programmer’s Guide that only static libraries can be linked. That only applies to Windows.

...and OS/2 (at least).

Tomas

Adriaan van Os
to Jonas Maebe: You have to mention the name of the dll in the procedure declaration: procedure test;…
Jonas Maebe wrote 16 lines
On 11 Mar 2010, at 12:28, Adriaan van Os wrote: > Marco van de Voort wrote: >> In our previous episode, Adriaan van Os said: >>> I am cross compiling with fpc svn trunk and -Twin32 on i386 Mac OS X >>> to Win32. This works fine, except that {$linklib xxx.dll} says >> dlls are usually not $linklib'ed in FPC. What happens if you simply >> omit the >> linklib? > > Well, then the linker complains about unresolved symbols. You have to mention the name of the dll in the procedure declaration: procedure test; stdcall; external 'dllname';

I assume ".dll" is added only if "dllname" doesn't have an extension ? For example, Apple's QuickTIme SDK for Windows is distributed with .lib files to link with and if I look up the corresponding ddl in the WIndows system32 directory, it is "QuickTime.qts", not "QuickTime.dll".

It looks like the dll is not checked at link-time to see if e.g. the stdcall-mangled names match and the routine is present ?

Thanks for the info, the software links now.

Regards,

Adriaan van Os

Tomas Hajny
to Adriaan van Os
Adriaan van Os wrote 23 lines
Jonas Maebe wrote: > On 11 Mar 2010, at 12:28, Adriaan van Os wrote: > >> Marco van de Voort wrote: >>> In our previous episode, Adriaan van Os said: >>>> I am cross compiling with fpc svn trunk and -Twin32 on i386 Mac OS X >>>> to Win32. This works fine, except that {$linklib xxx.dll} says >>> dlls are usually not $linklib'ed in FPC. What happens if you simply >>> omit the >>> linklib? >> >> Well, then the linker complains about unresolved symbols. > > You have to mention the name of the dll in the procedure declaration: > > procedure test; stdcall; external 'dllname'; I assume ".dll" is added only if "dllname" doesn't have an extension ? For example, Apple's QuickTIme SDK for Windows is distributed with .lib files to link with and if I look up the corresponding ddl in the WIndows system32 directory, it is "QuickTime.qts", not "QuickTime.dll".

Those .lib files are probably import libraries (these are necessary for some compilers which cannot generate the imports themselves on the fly).

It looks like the dll is not checked at link-time to see if e.g. the stdcall-mangled names match and the routine is present ?

The idea is that it should be possible to compile and link even without having all the DLLs installed on the development machine (otherwise cross-compilation would be rather difficult - I suspect that there may be no legal way of installing Windows system DLLs to a *nix machine).

Tomas

Marco van de Voort
to Adriaan van Os: I assume ".dll" is added only if "dllname" doesn't have an extension ? For example,…

In our previous episode, Adriaan van Os said:

Show quoted text 7 lines
>> Well, then the linker complains about unresolved symbols. > > You have to mention the name of the dll in the procedure declaration: > > procedure test; stdcall; external 'dllname'; I assume ".dll" is added only if "dllname" doesn't have an extension ?

yes. Also microsoft distributes dlls (+something extra) with different extensions, winspool.drv, hhctrl.ocx (not purely an activex interface, also contains normal procedures) etc.

For example, Apple's QuickTIme SDK for Windows is distributed with .lib files to link with and if I look up the corresponding ddl in the WIndows system32 directory, it is "QuickTime.qts", not "QuickTime.dll".

In that case I think the dllname should be complete, IOW 'quicktime.qts', casing doesn't matter.

It looks like the dll is not checked at link-time to see if e.g. the stdcall-mangled names match and the routine is present ?

That's correct. FPC probably does so out of Delphi compatibility.

Borland faced probably the following issues with Delphi:
* If they choose microsoft's importlib format, they would be exposed to breakage and catch-up issues if MS broke it. Keep in mind that VS didn't have the same dominant position then that it has now.
* if they introduced an own format, the problem would be chose an own format, but then have the trouble that most 3rd party dlls would be without borland specific import lib
* don't use importlibs, generate the necessarily tables, but don't try to match signatures.

Delphi apparantly chose the 3rd option, probably because it is the easiest supportable.

The problem with importlibs is first and for all that there are several formats, MSVC's (SDKs seem to come with a .lib per MSVC version, so multiple versions) and the various GCCs (*.a, but potentially dependant on the exact gcc/windows flavour (mingw,cygwin,other))