Category Archives: C++

Fixing Error LNK2038 In a Visual Studio Project

While building a Visual Studio C++ project in Visual Studio 2022, I received this error while linking to a library:

Error LNK2038 mismatch detected for ‘_MSC_VER’: value ‘1800’ doesn’t match value ‘1900’ in MidiPlayer.obj MIDIPlayer E:\code\MIDIPlayer\wxmsw30ud_core.lib(dlgcmn.obj)

In case you’re not familiar with this error, Visual Studio wants to link with libraries that were built with the same version of Microsoft C (same toolset) as the code you’re compiling. In older versions of Visual Studio that meant that they had been built with the same version of Visual Studio, but now that versions aren’t as tightly-coupled to Visual Studio, it’s also possible that you can get this with libraries built with the same version of Visual Studio that you’re using.

The solution is to rebuild the library with the same MSC version as your project.

For reference, here are the different MSC, MSVC, and toolset versions:

Microsoft C 6.0: _MSC_VER == 600
Microsoft C/C++ 7.0: _MSC_VER == 700
Microsoft Visual C++ 1.0: _MSC_VER == 800
Microsoft Visual C++ 2.0: _MSC_VER == 900
Microsoft Visual C++ 4.0: _MSC_VER == 1000
Microsoft Visual C++ 4.1: _MSC_VER == 1010
Microsoft Visual C++ 4.2: _MSC_VER == 1020
Microsoft Visual C++ 5.0: _MSC_VER == 1100 (Visual Studio 97)
Microsoft Visual C++ 6.0: _MSC_VER == 1200 (Visual Studio 6.0)
Microsoft Visual C++ 7.0: _MSC_VER == 1300 (Visual Studio 2002)
Microsoft Visual C++ 7.1: _MSC_VER == 1310 (Visual Studio 2003)
Microsoft Visual C++ 8.0: _MSC_VER == 1400 (Visual Studio 2005 – v80)
Microsoft Visual C++ 9.0: _MSC_VER == 1500 (Visual Studio 2008 – v90)
Microsoft Visual C++ 10.0: _MSC_VER == 1600 (Visual Studio 2010 – v100)
Microsoft Visual C++ 11.0: _MSC_VER == 1700 (Visual Studio 2012 – v110)
Microsoft Visual C++ 12.0: _MSC_VER == 1800 (Visual Studio 2013 – v120)
Microsoft Visual C++ 14.0: _MSC_VER == 1900 (Visual Studio 2015 – v140)
Microsoft Visual C++ 14.1 – 14.16: _MSC_VER == 1910 – 1916 (Visual Studio 2017 – v141)
Microsoft Visual C++ 14.2 – 14.29: _MSC_VER == 1920 – 1929 (Visual Studio 2019 – v142)
Microsoft Visual C++ 14.3: _MSC_VER == 1930 (Visual Studio 2022 – v143)

It’s interesting that starting with Visual Studio version 2017, Microsoft started incrementing the MSC version with each “micro” build change.

Updating a wxWidgets project for Visual Studio 2019

I recently resurrected a dormant code project and went through the process of converting a wxWidgets 3.0 project to wxWidgets 3.1 and updaing from Visual Studio 2010 to Visual Studio 2019.

Include Directories

Here are the things I had to change to make things build and run:

Change “Platform Toolset” to Visual Studio 2019 in General configuration properties.

Change include and library directories from wxWidgets 3.0.2 to 3.1.4 in VC++ Directories and update the include path for modern Visual Studio. The change to $(IncludePath) does a lot of magic things that will save a lot of trouble. Failure to update that will cause common includes like stdafx.h to be missing.

Change include from:
E:\lib\wxWidgets-3.0.2\include;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include
to:
E:\lib\wxWidgets-3.1.4\include;$(IncludePath)

Code

The only code changes I had to make were to remove wxADJUST_MINSIZE anywhere it showed up.

Libraries

This is for the debug version of the project. Remove the “d” for libraries in the release version (i.e. wxbase31ud_core.lib => wxbase31u_core.lib).

These libraries showed up as missing:

comctl32.lib
rpcrt4.lib
uuid.lib
kernel32.lib

Adding C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x86 to the linker directories fixed this.

msvcprtd.lib

Adding C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\lib\x86 to the linker directories fixed this.

ucrtd.lib

Adding C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x86 to the linker directories fixed this.

wxregexu.lib

Adding that to the library list fixed it.

I suspected there was something similar to $(IncludePath) I could add to the library paths to make those resolve, but I wasn’t sure. So I tried $(LibraryPath). And it worked. Magic!

So do that instead of adding those individual directories.

Change library path from:
E:\lib\wxWidgets-3.0.2\include;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include
to:
E:\lib\wxWidgets-3.1.4\include;$(IncludePath)

Update all the libraries from wx 3.0 versions to wx 3.1 versions:

wxmsw30ud_core.lib => wxmsw31ud_core.lib
wxbase30ud.lib => wxbase31ud.lib
wxmsw30ud_adv.lib => wxmsw31ud_adv.lib
wxmsw30ud_html.lib => wxmsw31ud_html.lib
wxmsw30ud_xrc.lib => wxmsw31ud_xrc.lib
wxbase30ud_net.lib => wxbase31ud_net.lib
wxbase30ud_xml.lib => wxbase31ud_xml.lib

After these changes I was able to build and run my old project, which was originally written for wxWidgets 2.8 and then ported to wxWidgets 3.0.

You Can Now MUD on webOS (TouchPad)

Much of my not-at-work development time has been spent on webOS lately.  The TouchPad and webOS version 3.x are great fun to work with and the only mobile devices that have APIs that don’t suck to develop for (I’ve worked with Android, iOS, and Win7 and none of them are fun from a C++ developer’s perspective).

Today my Telnet application was published in the catalog.  It’s still not perfect yet, but thanks to that application it’s now possible to MUD on the TouchPad.

Visual Studio 2010

Three months ago I switched from Visual Studio 2008 to Visual Studio 2010 as my main development environment.  Functionally it’s the same as it’s always been, but there are two things about it I consider great improvements.

First, the UI:  It looks so a lot better and cleaner than earlier versions.  It’s not that older versions were ugly, but it has a cleaner look and is much easier on the eye.

Next, C++ Development:  For the last few versions of VS, C++ developers have pretty much been shafted — no real feature improvements for the most part with all the love going to C#.  C++ received a major boost, gaining just-in-time compilation and error-detection intellisense almost exactly like C# has always had.  It doesn’t sound like a big deal, but it is excellent for speeding up the code-compile-fix cycle.

Only a small portion of Basternae code is in C++, just the client and the Basternae 2 to 3 zone converter, but it is a lot more pleasant to write with Visual Studio 2010.

This project started on Visual Studio 2003, so now we’ve been through four versions.

Visual C++ For C# Programmers

At my dayjob, I’m a C# developer. 2.5 years ago I was a C++ developer during the day. When I wrote C++, it was all for multiplatform applications that never touched any of the .NET libraries. When I switched to C#, it was all .NET. Never once did I try or even look into using any of the .NET libraries with C++. I knew there was something like __gcnew available, but I took one peek at managed C++ back in 2003 or so and got scared, running away because it looked so ugly.

I had heard that it was improved, but never bothered to look into it until now. I picked up a copy of Pro Visual C++ 2005 for C# Developers and in the first 50 pages I learned everything I need to know to be able to mix managed and unmanaged code in a C++ application, or to mix C# and C++ applications in a .NET project.  I’m not sure how much I’ll ever use that, since my main usage of C++ is for wxWidgets or Qt-based applications, but it’s nice to know, and the author, Dean Wills, did a damn fine job of explaining the differences between the two languages in a short amount of time.

The remainder of the book explains more of the intricacies and specifics, but any competent C# programmer can be writing C++ in only two hours with this book.

Should I learn C first? Or C++?

Every once in a while, a non-programmer interested in game programming will ask me where they should start learning. They’ll usually know that most modern programming languages are derived from or related to C and that most games are developed in C++, so the first question I hear will usually be:

Should I learn C first? Or C++?

My answer is: neither. I recommend learning C# first.

There are so many bad habits and terrible practices you can develop by starting with C or C++ first that it’s a bad road to go down. By starting with C# first you’ll be forced to learn how to develop object-oriented code instead of being able to mix an ugly blend of procedural and object code with no method to the madness.

The transition from C to C++ can be very easy — almost any code written in C will run unmodified in C++, with the biggest danger being that you might have used reserved keywords as variable names.

That’s very dangerous.

In C++ there are a lot of things that can be done that just shouldn’t be — especially global variables and constants, un-encapsulated data and procedural code, etc. The C++ compiler doesn’t care how badly-written your code is as long as you follow proper syntax. Some people spend years trying to “unlearn” C programming once they transition to C++. I know I had a hard time with it, and entire books have been written on the subject.

Instead, if you eventually end up making the transition from C# to C++, you’ll already be used to the idea of being able to use library functions and be less-inclined to “roll your own” version of things when you can find a library to take care of it for you. This will result in faster development — after all, it’s often far easier to plug something in or look up what’s available in the standard library than it is to write and debug new code, which C trains a programmer to do more often. Remember: an architect doesn’t reinvent the nail every time he designs a house.

Some other reasons to learn C# first:

  • C# is also good as a first language because it’s a very easy to make a transition to Java. Some people refer to C# as a “child of C++ and Java”.
  • With Microsoft’s Silverlight (designed as a Flash-killer), C# is also becoming more relevant for developing web-based games.
  • Every person I know that has tried to learn programming and given up has died at the same point: pointers. With C# you don’t have such a mind-boggling mess of things and are far less likely to have weird pointer-based crashes and glitches. You never have to learn the abstract insanity that is pointer arithmetic and memory manipulation. (void ** pointers still make me wake up screaming sometimes.

VS2005 Regular Expression Search Rules!

One of the things I had to do to eliminate a few thousand bugs as part of this C++ to C# conversion is replace the text transmission functions.

Nevermind how they work internally, the important thing for the sake of the current conversion is that they look completely different.

The old functions looked something like:

send_to_char( “Words.\n\r”, ch );

While the new functions are supposed to look like:

ch.SendText( “Words.” );

With around 4000 or so calls to that function, it would be a dauntingly huge project to retype every reference to send_to_char. Because it’s a bit more complicated than a simple word replace, we would be hosed if not for Visual Studio 2005’s regular expression search and replace.

If you Google regular expression search-and-replace, most likely you’ll come up with a lot of people complaining about it. Ignore them — those people are whiny idiots. It is easily one of the most useful things ever added to Visual Studio and it takes about 10-15 minutes to get the hang of.

To make the above change, all I had to do was do a search for:

send_to_char[(] {:q}, {:i} [)];

And replace it with:

\2.SendText( \1 );

As a basic explanation:

1. Anything in [] brackets means “any of these characters”. I had to bracket the parenthesis to keep the parser from evaluating them as an expression.
2. Anything in {} brackets means that it’s assigned an “expression tag”. It’s the equivalent of the scripting language act of assigning it to %0, %1, etc and they’re numbered in the order they are found.
3. :q means match a “quoted expression”.
4. :i means match a C++/C# identifier (i.e. a variable name).
5. \1 means “insert the first tagged expression”. \2 inserts the second, etc.

This is enough to get the basic idea going, and it works like a charm, provided the functions are spaced EXACTLY as indicated. If you have something like (notice spaces):

send_to_char(“Something” , ch );

It will not work. In any codebase that has had more than one person’s fingers in it, you’ll have inconsistent spacing. Some people will put spaces before/after every variable, some won’t, and some will be mixed. That’s why we have to set it to ignore spaces anywhere they will be a concern. We do this by inserting [ ]* which means “match anywhere from 0 to infinity spaces”. The search expression now looks like:

send_to_char[(][ ]*{:q},[ ]*{:i}[ ]*[)];

And now that I’ve figured out how to use regular expressions, all of the references to the Diku send_to_char function have been replaced with our shiny new code.

The error count is now down to 24,414.

Inheritance = A Good Thing

No, I didn’t just have some rich relative kick off and leave my name in the will. The closest I have to a rich relative is an uncle who can afford to buy a new pair of shoes every two years.

In the original MUD code and in most C-based codebases I’ve seen, mobs have one set of data and players have a similar but different set of data. They all have things like hitpoints and movement points, but mobs have things like AI scripts and behavior flags while players have extra things like skill values and guild memberships.

There are two ways to handle this in C: either have completely different sets of data for each, or have a core set of data and a pointer to the extended data depending on which type it is (player or mob). The first way is sloppy and dangerous, while the second is sort of a “poor man’s inheritance”.

I’ve rewritten this to use parent and derived classes and all of a sudden some things that were very hard to do are incredibly easy. It’s also become incredibly easy to have things work differently for mobs and players by being able to use overridden functions for the player versions of code.

For example, since mobs don’t have skill training, almost every check for something like a bash or headbutt is based on a combination of that mob’s level and racial statistics. For players the check uses skill values modified by actual attributes like dexterity and strength.

Instead of writing a huge function riddled with lots of “if” statements, I can now just write different versions for each. The code is cleaner, easier to write, and automatically smart enough to “do the right thing”.

I love C++. Even though I’m getting a bit addicted to C# lately, it still rocks.

I never could have made this change without massive use search-and-replace, since the way to access most of the data members of players has changed completely. I did not want to change 2000 data references by hand.

Visual Studio 2005

I’ve been using Visual Studio .Net 2003 for a long time. I’ve finally upgraded to 2005, and some of the changes are interesting.

One of the things I’ve been doing is converting a lot of the c-string functions to STL std::string. It turns out that the old string functions I’m gradually eliminating have been deprecated:

_snprintf: “This function or variable may be unsafe. Consider using _snprintf_s instead.”
strncat: “This function or variable may be unsafe. Consider using strncat_s instead.”
stricmp: “The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _stricmp”
fopen: “This function or variable may be unsafe. Consider using fopen_s instead.”
strncpy: “This function or variable may be unsafe. Considre using strncpy_s instead.”

I will gladly avoid using those functions. I hate them.

The Road To C++

I’ve gradually been changing more pieces of code from C to C++. As each piece goes from being a random function dangling somewhere to a piece of a coherent class the code begins to make a little more sense.

So many bits and pieces are going to benefit from being private data members. In a lot of cases there were hoops that had to be jumped through to handle values properly. Race, for instance. If a character was polymorphed into another race, some of the functions in the game would react to the new race and others would react as if nothing had happened, so a troll turned into a lizard might still lumber into the room.

With the ability to make some data members private, we can make it so that nobody can look at player->race, but instead have to call player->GetRace() which will be smart enough to check for polymorph. The same can be said for checking or adjusting ability scores, hitpoints, and all sorts of things that can be modified by spells.

It’s a phenomenally massive undertaking, but with the proper amounts of time and insanity it can be done right.