Sign in Join

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

Mailing lists / fpc-pascal / 2011-10

Linking to C++ DLL compiled with MSVC

6 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Michael Lutz

I've been trying to link to an external DLL which is unfortunately compiled using MSVC in C++ mode. The functions itself do not use any C++ features, they are just not declared as extern "C" and thus use name mangling.

With MSVC name mangling, each symbol starts with a '?' character, which seems to not play well with fpc in some situations. Below are two test cases, where the first one works and the second one fails. If I remove the '?' from the external name, both test cases compile and produce an EXE with the proper imports.

Unfortunately, the second one is the interesting one as not using units is no option. Is this is a genuine bug or is a symbol containing a '?' not supported in units by design?

$ cat test.pas
program Test;
procedure Dummy; external 'who_cares' name '?Dummy';
begin
  Dummy;
end.

$ fpc test.pas
Free Pascal Compiler version 2.4.4 [2011/09/29] for x86_64 Copyright (c) 1993-2010 by Florian Klaempfl
Target OS: Win64 for x64
Compiling test.pas
Linking test.exe
7 lines compiled, 0.1 sec , 32464 bytes code, 1664 bytes data

$ cat test2.pas
program Test2;
uses TestUnit;
begin
  Dummy;
end.
$ cat testunit.pas
unit TestUnit;
interface
procedure Dummy;
implementation
procedure Dummy; external 'who_cares' name '?Dummy';
end.

$ fpc test2.pas
Free Pascal Compiler version 2.4.4 [2011/09/29] for x86_64 Copyright (c) 1993-2010 by Florian Klaempfl
Target OS: Win64 for x64
Compiling test2.pas
Compiling testunit.pas
Linking test2.exe
test2.pas(7,1) Error: Undefined symbol: ?Dummy
test2.pas(7,1) Fatal: There were 1 errors compiling module, stopping Fatal: Compilation aborted

Reply by email

Sven Barth
to Michael Lutz
Michael Lutz wrote
Unfortunately, the second one is the interesting one as not using units is no option. Is this is a genuine bug or is a symbol containing a '?' not supported in units by design?

[skip]

Show quoted text 12 lines
$ cat testunit.pas unit TestUnit; interface procedure Dummy; implementation procedure Dummy; external 'who_cares' name '?Dummy'; end.

Move the "external ..." part to the interface and remove the one in the implementation section. This works at least for me and is the usual way of importing functions in their own unit.

Regards,
Sven

Reply by email

Sven Barth
to Michael Lutz: I've been trying to link to an external DLL which is unfortunately compiled using MSVC in…
Michael Lutz wrote
Unfortunately, the second one is the interesting one as not using units is no option. Is this is a genuine bug or is a symbol containing a '?' not supported in units by design?

[skip]

Show quoted text 12 lines
$ cat testunit.pas unit TestUnit; interface procedure Dummy; implementation procedure Dummy; external 'who_cares' name '?Dummy'; end.

Move the "external ..." part to the interface and remove the one in the implementation section. This works at least for me and is the usual way of importing functions in their own unit.

Regards,
Sven

Reply by email

Michael Lutz
to Sven Barth
Sven Barth wrote
Move the "external ..." part to the interface and remove the one in the implementation section. This works at least for me and is the usual way of importing functions in their own unit.

Thanks, that works. Summary of some more tests:
- 'external ...' in the interface section works
- 'external ...' in the implementation if the procedure is not declared in the interface section works
- 'external ...' in the implementation and a declaration in the interface section does NOT work

That probably should at least get a documentation line somewhere.

Thanks,
Michael

Reply by email

Sven Barth
to Michael Lutz
Michael Lutz wrote 13 lines
Am 10.10.2011 17:41 schrieb Sven Barth: > Move the "external ..." part to the interface and remove the one in the > implementation section. This works at least for me and is the usual way > of importing functions in their own unit. Thanks, that works. Summary of some more tests: - 'external ...' in the interface section works - 'external ...' in the implementation if the procedure is not declared in the interface section works - 'external ...' in the implementation and a declaration in the interface section does NOT work That probably should at least get a documentation line somewhere.

In my opinion this should be a bug, because at least Delphi allows to use the third variation. So could you report one, so it's not forgotten?

Regards,
Sven

Reply by email