[try Beta version]
Not logged in

 
Compiles with Visual Studio, but not g++

Aug 11, 2024 at 3:04am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <sstream>
#include <vector>
#include <filesystem>
#include <fstream>
#include <shlobj.h>
#include <locale>
#include <codecvt>
#include <windows.h>
#include "data.h"

// ...

int createShortcut(const std::string& path, const std::string& appName)
{
	std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;

	CoInitialize(NULL);
	IShellLink* pShellLink = NULL;
	HRESULT hres;
	hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL,
		IID_IShellLink, (void**)&pShellLink);

	if (SUCCEEDED(hres))
	{
		std::string filePath{ path + "\\" + appName};
		pShellLink->SetPath(filePath.c_str());
		pShellLink->SetDescription(appName.c_str());
		pShellLink->SetIconLocation(filePath.c_str(), 0);

		IPersistFile* pPersistFile;
		hres = pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile);

		if (SUCCEEDED(hres))
		{
			std::string linkPath{ getenv("USERPROFILE") };
			linkPath += "\\Desktop\\" + appName + ".lnk";
			std::wstring wLinkPath = converter.from_bytes(linkPath);
			hres = pPersistFile->Save(wLinkPath.c_str(), TRUE);
			pPersistFile->Release();
		}

		else
			return 2;

		pShellLink->Release();
	}

	else
		return 1;

	return 0;
}


This compiles fine in Visual Studio 2019 in a blank project without having to link anything or set additional include paths, but when I try to compile with g++, it fails with the following:

C:\Users\Admin\AppData\Local\HexLoader>g++ impl.cpp -o new.exe
C:/ProgramData/mingw64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\Admin\AppData\Local\Temp\ccfaepkX.o:impl.cpp:(.text+0x9af): undefined reference to `__imp_CoInitialize'
C:/ProgramData/mingw64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\Admin\AppData\Local\Temp\ccfaepkX.o:impl.cpp:(.text+0x9e5): undefined reference to `__imp_CoCreateInstance'
C:/ProgramData/mingw64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\Admin\AppData\Local\Temp\ccfaepkX.o:impl.cpp:(.rdata$.refptr.IID_IPersistFile[.refptr.IID_IPersistFile]+0x0): undefined reference to `IID_IPersistFile'
C:/ProgramData/mingw64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\Admin\AppData\Local\Temp\ccfaepkX.o:impl.cpp:(.rdata$.refptr.IID_IShellLinkA[.refptr.IID_IShellLinkA]+0x0): undefined reference to `IID_IShellLinkA'
collect2.exe: error: ld returned 1 exit status


I haven't used gcc/g++ very much. I read that the functions it can't find are defined in Ole32.lib, part of the Windows SDK, so I tried:

g++ impl.cpp -o new.exe -L"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64"


..and got the same output. Anyone know what I can do here?
Aug 11, 2024 at 6:47am
The -L option only tells the linker where to look.
You also need to use the -l option to state which library you want to actually reference.

As a guess, you might try -lole32

The GNU linker has some implied naming rules when on Linux, I don't know how those are implemented on Windows, so there might be a bit of fussing to get the syntax right.

You should also examine the build log of your VS build to see if further libraries are also required.
Aug 11, 2024 at 8:34am
Perhaps:
https://stackoverflow.com/questions/6705396/undefined-reference-to-imp-coinitialize4

VS by default will include certain lib files:

kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
odbc32.lib
odbccp32.lib

Other compilers may not and required ones may need to be manually included.
Aug 11, 2024 at 5:35pm
Cool thank you, I tried:

g++ impl.cpp -o new.exe -L"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64" -lole32 -luuid


and it gave me:

C:/ProgramData/mingw64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: new.exe:.retplne: section below image base


..but if I remove the search directory and just specify the libs:

g++ impl.cpp -o new.exe -lole32 -luuid


..it compiles.

My program generates data.h and impl.cpp in app data, and compiles a new bin with g++. It's a pretty lightweight application (and already needs to autoinstall chocolatey with PowerShell, then autoinstall MinGW with chocolatey) so I don't want the end user to have to download Win SDK as well. I'm thinking I'll just store the two lib files as resources, and write them to the app data folder before compilation.

Thanks again.
Aug 12, 2024 at 8:48am
When using GCC from MinGW (or mingw-w64), you should not use the -L option to add the Windows SDK "Lib" directory. That is because MinGW (or mingw-w64) already comes with its own import libraries and header files for the Win32 API! If you use -L option to add the Windows SDK "Lib" directory, then GCC will now link the import libraries from the Windows SDK, rather than linkingit its own ones – but it will still be using the MinGW-provided header files for compilation, because you haven't used the -I option! Of course, you could use option -I to force GCC to use the header files from the Windows SDK "Include" directory, in order to at least be consistent – but that may cause other problems. So, just use the header files and the import libraries that come with MinGW (or mingw-w64) and that's it 😏
Last edited on Aug 12, 2024 at 9:50am
Aug 24, 2024 at 4:38pm
The import libraries for the WinAPI are different for each compiler, a different format. It is recommended you use GCC libs for GCC/G++ and the WinAPI libs for MSVC.

GCC/MinGW links different machine code than what MSVC links even though it theoretically performs the same function(s).
Topic archived. No new replies allowed.