3

First up, I'm new to C++ (and MS VS), so I'm very probably missing something here. I do have some coding experience, though, and I'm having trouble discerning what might be escaping me.

I'm trying to use Logitech supplied .lib and .h files to control a G13 keyboard, by using the following code:

[Edit: This code, and error messages, has been altered to take into account points below from Mike Vine and Hans Passant (thanks guys!), but the issue still remains]

#include "pch.h"
#include <iostream>

#pragma comment(lib,"LogitechLCDLib")
#include "Include\LogitechLCDLib.h"

int main()
{
    wchar_t str[] = L"Hello";

    LogiLcdInit(str, 1);

    return 0;
}

However, I receive the following errors;

Error   LNK2019 unresolved external symbol "bool __cdecl LogiLcdInit(wchar_t *,int)" (?LogiLcdInit@@YA_NPAGH@Z) referenced in function _main    ConsoleApplication1 C:\Users\clewl\source\repos\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.obj 1   
Error   LNK1120 1 unresolved externals  ConsoleApplication1 C:\Users\clewl\source\repos\ConsoleApplication1\Debug\ConsoleApplication1.exe   1   

I've been around the houses a bit here - I initially though I was doing something wrong with wchar_t* (its new to me, as was const correctness), and then that, for some reason, the .lib wasn't being loaded.

However, I have now found the wonders of /VERBOSE (told you I was new to Visual Studio ;-) ), and have been comparing the output of my code with the (working) example supplied with the Logitech SDK.

I'm reasonably sure the .h is ok, as intellisense shows the definition, and the .lib file is being picked up correctly, as verbose build output shows lines such as

1>Starting pass 1
1>Processed /DEFAULTLIB:LogitechLCDLib

<snip>

1>    Searching C:\Users\clewl\source\repos\ConsoleApplication1\ConsoleApplication1\Lib\x64\LogitechLCDLib.lib: 

However, right at the end of the build output is

1> Unused libraries:

<snip>

1> C:\Users\clewl\source\repos\ConsoleApplication1\ConsoleApplication1\Lib\x64\LogitechLCDLib.lib

When I compare this with the build output from the working example, I see lines such as

1> Processed /DEFAULTLIB:LogitechLCDLib.lib

<snip>

1> LogitechLCDLib.lib(LogitechLCDLib.obj)
1> LogitechLCDLib.lib(stdafx.obj)

<snip>

1>    Searching ..\..\Lib\x86\LogitechLCDLib.lib:
1>      Found "bool __cdecl LogiLcdInit(wchar_t *,int)" (?LogiLcdInit@@YA_NPA_WH@Z)
1>        Referenced in LCDDemoDlg.obj
1>        Loaded LogitechLCDLib.lib(LogitechLCDLib.obj)
1>      Found ___@@_PchSym_@00@UyfrowztvmgUdlipUyIzCIHuEBIJHIIFJUhixUhwphUoxwUoltrgvxsoxworyUivovzhvUhgwzucOlyq@9DC0ED7C20F9DB3D
1>        Referenced in LogitechLCDLib.lib(LogitechLCDLib.obj)
1>        Loaded LogitechLCDLib.lib(stdafx.obj)

amongst others, and no reference to LogitechLCDLib.lib being an unused library.

Unfortunately, after a fairly intensive couple of days, my google fu appears to have given up on me, and I'm unable to progress any further. There are many examples of this linker error, but none seem to fix this case - incorrect /NODEFAUTLIB, or (as in the only case I can find using this library), just moving the #pragma comment line.

And so I throw myself before your superior knowledge and experience! If any of you kind people could tell me what egregious error I am making, or fundamental concept I'm missing, I would be very thankful.

I'm a little hesitant to post the full verbose logs, but if any further information is required, I'd be more than happy to provide it.

TL;DR - Bloke who thinks he can code can't perform basic tasks, but had a good go and asked very nicely. ;-)

Thanks for Reading!

Neal

NealC
  • 31
  • 3
  • Do note the mismatch between the function you found and the one it is looking for. unsigned short does not match wchar_t. This is a compile option, very unusual to change it. Project > Properties > C/C++ > Language > Treat WChar_t.... Changing the project template defaults starts at minus 100 points, this one at -10000. It only matters to code that was written 25 years ago. – Hans Passant Aug 28 '18 at 20:46
  • Also note that its pretty iffy that `LogiLCDInit` takes a *non-const* `wchar_t*`. Personally I'd avoid the const_cast and pass in a mutable string anyway. Just redeclare `wchar_t const * tmp = L"Hello";` as `wchar_t tmp[] = L"Hello";` and you can drop the cast. – Mike Vine Aug 28 '18 at 20:51
  • Thanks for pointing that out Hans (I'm afraid Mike beat you too it) - I apologise for the oversight, and have fixed that by creating a clean project and rebuilding - situation is identical apart from change in error message (from unsigned short to wchar_t). Everything else is identical. Mike, thanks for clarifying the wchar_t assignment for me. I'd appreciate any further ideas you may have (but I'm definitely calling it a day now!!) – NealC Aug 28 '18 at 22:01

1 Answers1

2

You need to make sure you're compiling with /Zc:wchar_t as in your snippet:

bool __cdecl LogiLcdInit(unsigned short *,int)

This thinks that the first parameter to LogiLcdInit is an unsigned int whereas in the working version:

bool __cdecl LogiLcdInit(wchar_t *,int)

You can clealy see its correctly a wchar_t. Now /Zc:wchar_t should be on by default but for whatever reason its not for you. If it isn't on you can find it in "Properties -> C/C++ -> Language -> Treat wchar_t as a built in type"

See this page for more information.

Mike Vine
  • 7,900
  • 21
  • 36
  • Thanks Mike, I should of noticed that before posting. I've made the suggested change and, unfortunately, the only difference I can see if the error is now LNK2019 unresolved external symbol "bool __cdecl LogiLcdInit(wchar_t *,int)" etc. I've probably changed that setting in my (unfocused) troubleshooting. I've just attempted to create a clean project, but VS isn't giving me quite the same files as it was (.cpp file now includes "pch." and , not "stdafx.h). I'll come back to it in the morning, create a clean project and let you know the results. Thanks Again! – NealC Aug 28 '18 at 21:05