Linker errors when compiling a DLL in VC++ 2005 EE.

Using Visual C++ 2005 Express, I'm writing a multi-threaded DLL, currently in the debug configuration (/MDd).

I'm trying to create a thread using _beginthreadex().  (I was using CreateThread() before, but I discovered a couple of web pages that advised against it.)

My relevant code is:

      class  _declspec(dllimport) MyClass {
            public:
                                          MyClass();
                  virtual                        ~McPerforceHud();
            private:
                  static unsigned WINAPI            thread(void*);
                  HANDLE                              hThread;
                  unsigned*                        threadID;
      };

MyClass::MyClass() {
      hThread = (HANDLE)_beginthreadex(NULL, 0, &thread, (void*)this, THREAD_PRIORITY_NORMAL, threadID);
}

unsigned WINAPI MyClass::thread(void* param) {
}


... and the result:


error LNK2019: unresolved external symbol __imp___beginthreadex referenced in function "public: __thiscall MyClass::MyClass(void)" (??0MyClass@@QAE@XZ)
error LNK2019: unresolved external symbol "__declspec(dllimport) const MyClass::`vftable'" (__imp_??_7MyClass@@6B@) referenced in function "public: __thiscall MyClass::MyClass(void)" (??0MyClass@@QAE@XZ)


Note that when I used CreateThread(), my DLL compiled without errors.  Only when I switched to _beginthreadex() did I start getting this Linker issues.


-- M. Cooper
MiloDCAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
Set the runtime library to 'multithreaded' (under Project Settings|C++|Code generation) and you'll get rid of that problem.
0
MiloDCAuthor Commented:
jkr wrote: "Set the runtime library to 'multithreaded' (under Project Settings|C++|Code generation) and you'll get rid of that problem."

I *knew* someone was going to reply with that.

As I wrote (first thing):

"Using Visual C++ 2005 Express, I'm writing a multi-threaded DLL, currently in the debug configuration (/MDd)."

/Mdd is "multi-threaded debug DLL."

If you mean that I should switch to /MT instead of /MDd, then I get even more errors when I try that.


-- M. Cooper
0
MiloDCAuthor Commented:
OK, I've managed to whack the second error:


error LNK2019: unresolved external symbol "__declspec(dllimport) const MyClass::`vftable'" (__imp_??_7MyClass@@6B@) referenced in function "public: __thiscall MyClass::MyClass(void)" (??0MyClass@@QAE@XZ)


Problem there was that I was declaring the destructor as a virtual function (silly me).

The first error (the one that has really given me a headache) persists.  I cannot figure out why _beginthreadex() isn't recognized by the linker.  (Yes, I have included process.h.)

I wonder if this is a mixed DLL issue?


-- M. Cooper
0
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

MiloDCAuthor Commented:
Further progress:

I added msvcrtd.lib to my dependency list.  That eliminated the __imp__ error.

Problem now is that msvcrtd.lib is clashing with libcmt.lib, causing "LNK2005: ... already defined in libcmt.lib" errors.

Adding "libcmt.lib" to the "Ignore Specific Library" field doesn't get me past this problem.

ARGH!


-- M. Cooper
0
Deepu AbrahamR & D Engineering ManagerCommented:
I think you have done this, Just confirming....
In project settings->link tab->category slelect 'Input'->under ignore libraries->
put one of the library which is clashing.

Is this what you did?
Best Regards,
DeepuAbrahamK
0
MiloDCAuthor Commented:
DeepuAbrahamK: "I think you have done this, Just confirming....
In project settings->link tab->category slelect 'Input'->under ignore libraries->
put one of the library which is clashing."

Hey man, yeah, I tried that, with the result that I traded one type of error for another.  Solving a problem just seems to lead to another one, ad infinitum.

Here's the story so far:

To get rid of the __imp__ error, I added "msvcrtd.lib" to my dependencies.  That leads to a bunch of "msvcrtd.lib(MSVCR80D.dll) : error LNK2005: [something] already defined in libcmt.lib" errors.

To get rid of *these* problems, I remove libcmt.lib from my dependencies.  That, in turn, leads to several "libsupp.lib([something].obj) : error LNK2001: unresolved external symbol __iob" errors.

This is just silly.  There's got to be some way for me to resolve declarations made in multiple libraries.


-- M. Cooper
0
MiloDCAuthor Commented:
I give up.  Looks like msvcrt(d).lib and libcmt(d).lib are incompatible, i.e. you can have one or the other but not both.  Other code in my project apparently relies on libcmt(d).lib, so I guess I'm stuck with that.


-- M. Cooper
0
itsmeandnobodyelseCommented:
>>>> I give up.  Looks like msvcrt(d).lib and libcmt(d).lib are incompatible
Not exactly, but they are defining the same modules so it is important which was first and which was second.

Generally, if using msvcrt you don't need libcmt. The beginthreadex is included in msvcrt as well but you need to have the multithreading option with all modules you are using. If you are using a dll or static library (from a third-party) where the multi-threading isn't set you'll get the problems as you described.

Did you use precompiled headers (PCH)? If yes, this might be the reason why your change from single-threaded to multi-threaded didn't work properly. Unfortunately precompiled header files often were not recompiled after changing the settings (or not all obejcts relying on PCH were recompiled to use the new PCH)., so that via PCH you might still have the old settings not containing the multi-threaded switch.

Anyhow, to solve the problem you first should remove the libcmt(d) lib. Then check that all projects and sub projects have the multed-threaded property in code generation both for debung and release. Note, dlls have as default single-threaded (unfortunately) when created by a wizard. After that make a clean on *all* projects and rebuild them regarding the correct dependencies. If you still get linker errors you should check the object modules that were related to the linker errors. Post the linker settings of the projects the modules belong to.


Regards, Alex
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.