undefined reference to `LoadIconMetric'

External libraries (GTK, GSL, SDL, Allegro, OpenGL, etc) questions.
stephanbrunker
Posts: 62
Joined: Nov 02, 2013 14:57

undefined reference to `LoadIconMetric'

Post by stephanbrunker »

Hello,

LoadIconMetric is declared in the comctrl.bi, but the linker throws an error: undefined reference to `LoadIconMetric'

I found that bugfix on the minGW repository:
https://github.com/ctaggart/mingw-w64/c ... bb25d5fc62

It seems that the FB libs are derived from the MinGW ones. So how do i implement that bugfix and to what file ... the libcomctrl32.dll.a ?

Unfortunately, I don't have a clue about compiler issues other than the headers.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: undefined reference to `LoadIconMetric'

Post by Josep Roca »

You can use a wrapper function, as I do:

Code: Select all

' ========================================================================================
' Loads a specified icon resource with a client-specified system metric.
' See: https://msdn.microsoft.com/en-us/library/windows/desktop/bb775701(v=vs.85).aspx
' ========================================================================================
PRIVATE FUNCTION AfxLoadIconMetric (BYVAL hinst AS HINSTANCE, BYVAL pszName AS PCWSTR, BYVAL lims AS LONG, BYVAL phico AS HICON PTR) AS HRESULT
   DIM AS ANY PTR pLib = DyLibLoad("Comctl32.dll")
   IF pLib = NULL THEN EXIT FUNCTION
   DIM pLoadIconMetric AS FUNCTION (BYVAL hinst AS HINSTANCE, BYVAL pszName AS PCWSTR, BYVAL lims AS LONG, BYVAL phico AS HICON PTR) AS HRESULT
   pLoadIconMetric = DyLibSymbol(pLib, "LoadIconMetric")
   IF pLoadIconMetric THEN FUNCTION = pLoadIconMetric(hinst, pszName, lims, phico)
   DyLibFree(pLib)
END FUNCTION
' ========================================================================================
Last edited by Josep Roca on Aug 25, 2017 19:50, edited 2 times in total.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: undefined reference to `LoadIconMetric'

Post by MrSwiss »

Hi,

which OS version are you using?
It appears that LoadIconMetric is only supported on NT: version 6.02 (aka: Win 8.0)

It's declaration is wrapped in a "conditional", which is probably not correct.

Code: Select all

#if _WIN32_WINNT = &h0602    ' I'd try first (instead of [=]), [>=] (Win 8.1 and Win 10 also)
	type _LI_METRIC as long
	enum
		LIM_SMALL
		LIM_LARGE
	end enum

	declare function LoadIconMetric(byval hinst as HINSTANCE, byval pszName as PCWSTR, byval lims as long, byval phico as HICON ptr) as HRESULT
	declare function LoadIconWithScaleDown(byval hinst as HINSTANCE, byval pszName as PCWSTR, byval cx as long, byval cy as long, byval phico as HICON ptr) as HRESULT
#endif
[edit] Seems, to be different (upon closer inspection): MS states: min. Desktop Client "Vista" (v. 6.00).
This implicitly means: NO Win XP support! [/edit]

Code: Select all

#if _WIN32_WINNT >= &h0600    ' would be IMHO, the correct check
Last edited by MrSwiss on Aug 25, 2017 16:14, edited 1 time in total.
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: undefined reference to `LoadIconMetric'

Post by St_W »

stephanbrunker wrote:It seems that the FB libs are derived from the MinGW ones. So how do i implement that bugfix and to what file ... the libcomctrl32.dll.a ?
The easiest solution is probably to take the import libraries from the Windows SDK instead of the one(s) provided with FB. Afaik the WinSDK import libraries are directly taken from the MinGW distribution used for building the compiler instead of generating them again. In case you're interested how to build import libraries from DLL+DEF files download 'dlltool', which is the MinGW tool to do that.

For convenience I've uploaded the library from the Windows 10 SDK. You can download it from here:
http://users.freebasic-portal.de/stw/fi ... K-libs.zip

Replace the according import libraries in you FreeBasic libs folder. You can rename the files to lib[...].a or lib[...].dll.a instead of [...].a - FreeBasic will search all variants. Just ensure that you replace or remove the old files so that they are not taken instead (e.g. move them to a lib-backup folder). I've also included crypt32 as there were similar issues with that recently.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: undefined reference to `LoadIconMetric'

Post by MrSwiss »

For those, still *sitting* on Win XP, use LoadIcon, instead ... (deprecated).

IMHO, the declaration LoadIconMetric is missing, due to .bi (header) error, not the import lib.
stephanbrunker
Posts: 62
Joined: Nov 02, 2013 14:57

Re: undefined reference to `LoadIconMetric'

Post by stephanbrunker »

I tried some things. First, the conditionals for LoadIconMetric are wrong (same is true for Shell_NotifyIcon). That was easy and i fixed that first before I even posted here. (I compile with #Define _WIN32_WINNT &h0602)

But even if the functions are now declared, they get not found by the compiler, thats the error I posted first. That means the declaration is not in the import library. There was the thread about commitments to the compiler and I would fix the headers and import libraries with a push request at github, but I don't get it how to create a working import libcomctl32 library. With the lib from ST_W the prog compiles, but throws an error on program start.

The minGW-64 libcomctl32.a is "incompatible" if renamed to .dll.a

The dylibload version also doesn't work - it also compiles without errors, but crashes when the function is called. That parameter 2 is an Unicode String PTR shouldn't matter if I use MAKEINTRESOURCE.

If I call the old style

Code: Select all

hIcon1 = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_ICON1))
then everything is ok, but I simply can't get the LoadIconMetric() to work and I really would like to make an Notify Icon example/tutorial out of that and the original windows sample uses this function because of the high dpi functionality. So how the hell are the FB import libraries made?
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: undefined reference to `LoadIconMetric'

Post by Josep Roca »

The dylibload version also doesn't work - it also compiles without errors, but crashes when the function is called.
Works here, e.g.

Code: Select all

DIM phico AS HICON
DIM hr AS HRESULT = AfxLoadIconMetric(NULL, IDI_APPLICATION, LIM_LARGE, @phico)
That parameter 2 is an Unicode String PTR shouldn't matter if I use MAKEINTRESOURCE.
It depends if you have UNICODE defined or not. MAKEINTRESOURCEW is what you have to use.

BTW that function requires the use of an appropriate manifest because it is in commctrl.dll 6.0+

Please note that I have reposted the function. This duplicated line should not have been there:

FUNCTION = pLoadIconMetric(hinst, pszName, lims, phico)

Maybe you aren't using an appropriate manifest and the function was crashing because pLoadIconMetric was null?
stephanbrunker
Posts: 62
Joined: Nov 02, 2013 14:57

Re: undefined reference to `LoadIconMetric'

Post by stephanbrunker »

Josep Roca wrote:
BTW that function requires the use of an appropriate manifest because it is in commctrl.dll 6.0+
Eureka!

After a lot of tries I got it it working. Means that I have now a working libcomctl32.dll.a which I can put in the repository with a push request. The problem was that the previous manuals here in the forum how to create that import library were simply outdated.

So, here the manual for FB1.05 first the 64bit Version:
You need:
  • the dlltool from FB\bin\win64, in the following $FB_BINPATH$
  • the pexports.exe from MinGW also copied into $FB_BINPATH$
  • the windows DLL into your workfolder with write access alias $WORKPATH$
First, creating the *.def file with pexports:

Code: Select all

cd [i]$WORKPATH$[/i]
$FB_BINPATH$\pexports comctl32.dll > comctl32.def
The problem is that the result is not complete. For example the LoadIconMetric entry is missing from that automatically created file, and you have to remove trash like

Code: Select all

#78 DATA ; WARNING: Symbol name guessed from forwarder (SHUNIMPL.#78)
.

Different from the previous manuals which were written for 32bit FB, the entries for the 64bit dll doesn't have a @4 or so suffix for the functions! I found that out by open the .dll.a with a hex editor and in the original FB versions, there was no @ in the file - and the -k parameter for the dlltool doesn't work. So you need to aquire a *.def file which is complete and without the @. You can get it in the MinGW git: https://sourceforge.net/p/mingw-w64/min ... crt/lib64/

Then you create the import library with

Code: Select all

$FB_BINPATH$\dlltool -d comctl32.def -l libcomctl32.dll.a
It seems that the dlltool and the dll cannot be in the same folder, because than you get a result file with 0 bytes.

Copy the resulting dll.a into the FB\Lib\win64 folder, your code should compile now without errors.

Without the MANIFEST, you get the error "Das System kann den angegebenen Einsprungpunkt nicht finden" at program start. Thats what I got with the dynamically loaded dll too without the manifest and with the *.lib from the Windows SDK.

For 32bit FB, this is different because here the @ are in the library.
now, the command is different with the -k option:

Code: Select all

$FB_BINPATH$\dlltool -d comctl32.def -l libcomctl32.dll.a -k
stephanbrunker
Posts: 62
Joined: Nov 02, 2013 14:57

Re: undefined reference to `LoadIconMetric'

Post by stephanbrunker »

You don't make it easy to commit ...

I have cloned the fbc repository at github and commited the changes in comctrl32.bi and shellapi.bi. And did a pull request. I still have to find out how to use Git correctly with a clone at my computer and so on, but for these little changes that was ok.

I also wanted to change the libcomctrl32.dll.a files for the 32bit and 64bit installation, but these are not in the repository. So, where I have to dump these? I found some *.def files, but these doesn't include comctl32.def , i have also the two versions of these. And it seems that the 64bit FB isn't even in the github repository ...

If you made commiting that hard, it would be easier to write a patcher which replaces those files at the users installation ...
stephanbrunker
Posts: 62
Joined: Nov 02, 2013 14:57

Re: undefined reference to `LoadIconMetric'

Post by stephanbrunker »

Nice ... after some digging I found the master/lib/win32/makefile which looks like the import libraries are simply copied from minGW like I assumed in my first post and it looked like the issue was fixed in March 2017 for MinGW64. So, wonderful - I commited hours simply because no one was able to give that information away. On the other hand it seems nobody knows when or even if a FB 1.06 version will come out and fix the issue. So if I publish my code, I'm going to put a patcher zip into it with the patched headers and libs.

I really like FB and I'd like to help, but there has to be at least a structure be published who to call for which issues so the help arrives at the right place or the other way round which way is the most effective to fix a certain bug.
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: undefined reference to `LoadIconMetric'

Post by St_W »

St_W wrote:[...] the WinSDK import libraries are directly taken from the MinGW distribution used for building the compiler instead of generating them again. In case you're interested how to build import libraries from DLL+DEF files download 'dlltool', which is the MinGW tool to do that.
Please read carefully instead of complaining. ;-)

Additionally please note that FB is maintained by volunteers and IMHO you've received a lot of helpful answers - especially when considering that only about 24 hours passed since the original question.

Anyway, thanks for your contribution, the changes look fine. Additionally it would be interesting whether this has been already fixed in the MinGW headers.
stephanbrunker
Posts: 62
Joined: Nov 02, 2013 14:57

Re: undefined reference to `LoadIconMetric'

Post by stephanbrunker »

Okay, there might be an misunderstanding. You wrote the "WinSDK import libraries" and meant the libraries in FB/lib/win32 or win64. But they are not directly taken from the MinGW distribution - i tried that first, but the MinGW .a files don't work. Same if you try to create them with the MinGW dlltool - or didn't tried the right combination of def -file, dlltool and dlltool options and so on, they are quite specific. And you mentioned the import libraries *.lib from the Windows SDK which is a different party. And it also doesn't help that there is MinGW and mingw-w64 which are also two different parties. As mentioned above, I did it but it could've been easier with the right information from the start because I didn't wanted to create a workaround, but a lasting improvement of the project. If your goal was that I'm going to learn a lot of this stuff, you succeeded ;-)

And speaking of the mingw-w64 def files (couldn't find the MinGW ones and I don't even know if MinGW does also do x64-compiling):
Not easy to find on the web, a little bit hidden under /git in on the SF page.

I can confirm that here:
https://sourceforge.net/p/mingw-w64/min ... w-w64-crt/

LoadIconMetric is added to /lib32/comctrl32.def
It was perhaps added to /lib64/comctrl32.def as well, but a later commit erased that file so that there is no according comctrl32.def in the /lib64 folder now. So perhaps it needs a later fix if libraries are build automatically from this repository. I cannot tell if that is the right one, that information is still unclear.

If I am complaining that is just that I got help requests related to my published projects too and I cannot imagine a single one of these people solving that riddle above given these few pointers which are partially incorrect/missunderstandable. But I am trying to decide if I'm going to learn how git is used correctly (searching for a good how-to and reading it and try it out) and getting all these repositories if I need to do something like that in the future again or if it was a one-time-problem ... I cannot help it that I don't do any programming-related work professionally and so I don't know any of this stuff ... only what I was forced to find out on my own.

PS: The windows headers and libraries have improved a lot since FB 0.90, that is for sure ...
PPS: As I found out, the *.def are different for x86 and x64. So I have these questions:
- is MinGW or mingw-w64 the base for FB libs?
- if special def are needed for FB, where are they in the FB repo for x86 and x64 - i found only some x86 ones.
- is the dlltool in the FB /bin folder a 100% copy of the minGW one , and which one? I got an "not compatible" error for some of my tries.
- what is the difference in the source for FB 32bit and 64bit packages (regarding the headers/libs), are they built from the same repository or is someone else managing the x64 project and has his own source?
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: undefined reference to `LoadIconMetric'

Post by St_W »

stephanbrunker wrote:Okay, there might be an misunderstanding. You wrote the "WinSDK import libraries" and meant the libraries in FB/lib/win32 or win64. [...]
Yes, I'm sorry for using wrong and unclear terms here. Also with "MinGW" I did not mean the old MinGW.org toolchain which was used for FB <= 0.9x and is x86-only, but the current MinGW-w64 toolchain, which is used since FB 1.0. You can find the toolchain used for building the official release package in the release announcement; e.g. here for 1.05: viewtopic.php?f=1&t=24363

And the import libraries are directly taken from the according MinGW version that was used to build the compiler. So for 1.05 the libs are taken from mingw-w64 i686-5.2.0-release-win32-sjlj-rt_v4-rev0.7z
In the mingw package they are named lib*.a; for FB they are renamed to lib*.dll.a - but otherwise binary identical.
I think you already mentioned it, but here's the according part in the makefile that does the copying: https://github.com/freebasic/fbc/blob/m ... efile#L989

The name should not be important as I've mentioned above: it shouldn't matter whether the filename is lib*.a, *.lib or lib*.dll.a
There shouldn't be any problems either when using the import libraries from the official Windows SDK from Microsoft.
stephanbrunker wrote:If I am complaining that is just that I got help requests related to my published projects too and I cannot imagine a single one of these people solving that riddle above given these few pointers which are partially incorrect/missunderstandable. But I am trying to decide if I'm going to learn how git is used correctly (searching for a good how-to and reading it and try it out) and getting all these repositories if I need to do something like that in the future again or if it was a one-time-problem ...
I've to admit that anwers were misleading or incorrect sometimes (and thus not really helpful) but I'm sure that everyone tried to answer to the best of one's knowledge. You seem to already know everything you need to contribute to FB: fork fbc, create a branch, commit & push, and finally create a pull-request. Anyway, there are lots of resources regarding the use of git out there and you can find existing answers for practically every git operation you'll ever need.
stephanbrunker wrote:PPS: As I found out, the *.def are different for x86 and x64. So I have these questions:
- is MinGW or mingw-w64 the base for FB libs?
- if special def are needed for FB, where are they in the FB repo for x86 and x64 - i found only some x86 ones.
- is the dlltool in the FB /bin folder a 100% copy of the minGW one , and which one? I got an "not compatible" error for some of my tries.
- what is the difference in the source for FB 32bit and 64bit packages (regarding the headers/libs), are they built from the same repository or is someone else managing the x64 project and has his own source?
a) the toolchain used for building the compiler itself (or, to be more precise, the compiler's runtime library + the gfxlib) is "base for FB libs". Currently this is some mingw-w64 version for both x86 and x64.
b) no special def nor special libraries needed. the def files you'll find in the FB repository are for some 3rd party libraries that are not included in mingw
c) I'd say: yes and regarding the toolchain see a), but for 1.05 they are not 100% binary identical - there are some differences in the PE header. I don't know where those come from, but I don't think that they do have any relevance as the rest of the executable is identical.
d) all packages for any OS or architecture are built from the same sources. The headers are basically identical, there are just some that are removed from the 64-bit package because they are not 64-bit compatible (yet). You'll find that also in the makefile exactly here: https://github.com/freebasic/fbc/blob/m ... efile#L848
The libs for Windows are taken from the according toolchain, see a). Packages for other platforms do not ship with import libraries as the OS either doesn't support libraries (DOS) or libraries are installed globally at a system-wide level (Linux, BSD, and other Unix-based systems).

speaking of headers: with
St_W wrote:Additionally it would be interesting whether this has been already fixed in the MinGW headers.
I actually meant the library headers that are shipping with MinGW, so the *.h files corresponding to FB's *.bi files. The reason is that most - if not all - of the headers are generated - to some extent - from their according C headers. This includes the Windows headers. I don't know how many manual fixes are necessary from the automated generation process to the final headers in the FB git repository, but there are probably quite a lot. For more information on the generation see this Git repo:
https://github.com/dkl/fbbindings
I don't know whether anyone can help if you've questions on that as that's the sole work of dkl and he's probably also the only one that could answer questions on this. For my part, I've never tried those scripts and only have taken a quick look once or twice. As you may have noticed unfortunately dkl has stopped his active FB development and thus probably isn't very active here on the forums as well, but I'm sure he'll answer (reasonable) questions via mail.

In the long-term it would be better to fix errors in the automated header generation instead of fixing the FB headers directly.
stephanbrunker
Posts: 62
Joined: Nov 02, 2013 14:57

Re: undefined reference to `LoadIconMetric'

Post by stephanbrunker »

Thank you - that is a lot of info. So, for the moment I create a patch for the changed files and then let us hope that the community can manage the maintenance without dkl. Unfortunately, that part is waaay out of my pay grade ...

PS:
looks like CalculatePopupWindowPosition is not declared in user32.dll.a too ... but now I know how to fix it.
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: undefined reference to `LoadIconMetric'

Post by dkl »

Hi,

Thanks for taking a look at these problems. That's exactly the kind of technical problems you have to deal with in FB for Windows.

I'd like to mention that the current winapi headers were mostly auto-translated with fbfrog, which is why the UNICODE/_WIN32_WINNT #ifs are somewhat ugly. I limited it to 3 values for _WIN32_WINNT (&h0400, &h0502, &h0602), because otherwise it would have been too much data to process. But it could be improved with better tools.

By the way, if you're interested in updating the winapi headers, in theory it's as "easy" as going into the fbbindings makefile on the "raw" branch, bumping MINGWW64_TITLE := mingw-w64-v4.0.4 to a newer version, and running "make winapi", and merging back to master. It's quite possible though that new fixups are needed (either via fbfrog options on "raw", or manually in "master"), if complex stuff was added to the .h files...
Post Reply