views:

2249

answers:

3

My VC++ solution includes two projects, an application (exe) and a static library.

Both compile fine, but fail to link. I'm getting an "unresolved external symbol" error for each function from the static lib I use. They look like this:

MyApplication.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) int __cdecl MyStaticLibrary::accept(int,struct sockaddr *,int *)"

The app find's the .lib just fine, so that is not the issue. I'm thinking the "dllimport" is the problem -- why would it be there when I'm trying to build a static library? Both the app and library use the "Multi-threaded (/MT)" runtime library, not "Multi-threaded DLL (/MD)".

EDIT:

I think some of the answers are right. The library, which is called UDT, has this in the main header file:

#ifdef UDT_EXPORTS
   #define UDT_API __declspec(dllexport)
#else
   #define UDT_API __declspec(dllimport)
#endif

Does this mean it wasn't meant to be used as a static library?

A: 

Since you're working with sockets, make sure to add WS2_32.lib in the additional dependencies of the project.

Suvesh Pratapa
Yep I have that included, thank you for checking though.
You usually get such an error by not adding the library. That's strange. Are you sure you have it under additional dependencies? Try putting it in the general libs section too.
Suvesh Pratapa
It's complaining about his class method accept, not the winsock accept function.
Gerald
+2  A: 

How are you setting it up to link? And what does your header file for MyApplication and MyStaticLibrary::accept look like?

If you have both projects in the same solution file, the best way to set it up to link is to right-click the Solution file->Properties and then set the library as a dependency of the application. Visual Studio will handle the linking automatically, and also make sure that the library build is up to date when you build your application.

That error kinda sounds like you have it defined as a DLL import/export in your header file though.

Edit: Yes, that's the problem. You probably created it as a dynamic library first? (or whoever wrote it did.)

There are a few options.

1) You can just delete all of that stuff, and any UDT_API modifiers in the code.

2) You can delete that stuff and add this line:

#define UDT_API

3) A more robust solution is to change it to this:

#ifdef  UDT_STATIC
    #define UDT_API
#else
    #ifdef UDT_EXPORTS
       #define UDT_API __declspec(dllexport)
    #else
       #define UDT_API __declspec(dllimport)
    #endif
#endif

And then add the preprocessor directive UDT_STATIC to your projects when you want to use it as a static library, and remove it if you want to use it as a dynamic library. (Will need to be added to both projects.)

Gerald
Check my edit above for more info, I think this is the reason.
Hmm, using the robust solution above still generates the same errors, only now __declspec(dllexport) is __declspec(dllimport). I may just need to bite the bullet and overhaul my solution to use DLLs.
Did you add UDT_STATIC to the preprocessor directives in both projects, and rebuild both?
Gerald
One other thing. In the library, make sure you changed the project to be a static library. i.e. go to the project settings for the library, go to Genera, and change "Configuration Type" to Static Library. Then go to Preprocessor definitions and remove the _USRDLL definition.
Gerald
Oh wow, I forgot to add UDT_STATIC to the application project. It finally linked successfully, thank you Gerald! I really appreciate the help, I would've never figured this out on my own.
A: 

It looks like the exported functions in the static library have the wrong calling convention. How does the header file for the exported functions look like?

Ok, so the functions are using UDT_API as prefix. They shouldn't if you are just creating a static .lib to link against.

An alternative is to change the lib to create a dll instead. So you create static linkage with a dll. Only problem is that you have to provide the dll with your app. Still not a bad solution, since it enables you to do fixes in the lib.

Magnus Skog
You may be right, check my edit at the top for more info.