April 22nd, 2003, 09:56 AM
Problems with linking in VC++
I'm having problems trying to use a static library in a new project. The library is my own, created using VC++ as well, and it compiles fine.
In a new project, I include "3D Maths.lib" on the Link Pane of the project settings, and #include "3D Maths.h" at the top of the main source file.
3D Maths.h contains a Vector class, which has operators defined on it such as +=, << etc. (Note this is a Vector as in 3D positional information, not vector<int> etc).
The portion of the code in the new project looks like this:
#include "3D Maths.h"
Vector v1(1.0, 2.0, 3.0);
Vector v2(0.5, 2.1, 1.6);
v1 += v2;
The error I get is with link.exe:
"public class Vector __thiscall Vector::operator+=(class Vector)"
The code compiles fine because cl.exe completes fully. In the past I've always fixed problems like this by just including the the necessary .lib file, so I'm confused because that doesn't work here.
Also confusing is that the Vector constructor doesn't give a linker error, and yet its implementation is in the same file as the += operator.
I'm using VC++ 6.0 Service Pack 5.
Finally, if I put all the code for the Vector class in the same file as main() it compiles and links successfully.
Thanks in advance for any help you could give.
April 22nd, 2003, 11:58 AM
What directory is your "3D Maths.lib" in? VC++ setup contains a list of directories for it to search in for libraries. Is you new library in one of those directories?
Also, Windows and VC++ will probably not mind, but I'm a bit leery of using filenames with embedded spaces in a situation like this. Or perhaps the name also needs to be quoted in the library list?
April 23rd, 2003, 05:24 AM
Do you mean on the Link panel of Project Settings? I've already put it in there, surrounded by " ". It finds the library ok, because the constructor implementation code executes. It just can't find code that implements the class methods... Very confusing.
PS: I added the directory that the library was in to the library directories list in Tools->Options->Directories, so I don't think that's the problem?
Any other ideas?
April 23rd, 2003, 10:14 AM
Is it possible that your .lib file does not contain the += operator implementation?
I've not played with making my own libraries, but there should be a library utility for listing the functions provided by a library, similar to the nm utility in Linux. Could you please verify that the operator implementation is indeed in the library? I would think that it would show up as the mangled name you get in the link error.
April 24th, 2003, 04:58 AM
Hadn't thought of that, - I'll have a look and get back...
April 24th, 2003, 01:50 PM
April 25th, 2003, 11:31 AM
OK, so I ran dumpbin /symbols and dumpbin /headers and it looks like the library doesn't contain any of the implementation code except the constructors!
Now I'm really confused. If it comes from the same source .cpp file and is part of the same class, all defined in one .h file, why is part of the class being implemented and not the rest?
There must be an option that I haven't checked somewhere in VC++? Has this happened to anyone else? It's a standard
New->Project->Static Library project
The library also contains classes for Matrix and Quaternion, as well as Vector, and the same thing's happened for those classes too - constructors, but no methods.
Thanks for the ongoing help, much appreciated!
April 25th, 2003, 12:32 PM
Try /exports and see what it tells you.
April 27th, 2003, 10:17 AM
OK, so I ran dumpbin /exports "3D Maths.lib" and the ouptut was almost empty, apart from the header, and the file info at the bottom.
I ran the same command on opengl32.lib to see what I should be getting and, as expected, there's a huge long list of decorated function names.
This means that my library essentially has nothing in it, doesn't it? I've been all over the web, and read loads of tutorials on how to create a static library and they all boil down to the following:
Create a new static library project.
Add the source and header files.
Use your new library.
As far as I can tell, there's no need for any options to be selected, unless debugging symbols etc. are required.
What might be a good idea is if somebody who has written a library of their own could just post a copy of the long-handed linker options they used in VC++, from the link section of their project options. I could then compare this and see if I'm missing any switches.
Could someone do this for me?
April 27th, 2003, 12:32 PM
A quick stupid question to eliminate a possibility.
You didn't declare those functions with the static qualifier, did you? Because that would prevent them from being accessible outside of their module.
You said in your first posting:
If the functions were declared with static, that would still work. Instead, you should run that test by keeping them in a separate file and adding that file to the project. Like the same file that you're using to create the static library.
Let us know how it turns out.
Last edited by dwise1_aol; April 27th, 2003 at 12:35 PM.
April 29th, 2003, 05:46 PM
Ok, here's what happened:
I included the code like you suggested, as a source file, instead of a library, and I still got the same errors. Needless to say, this wasn't what I expected...
So I looked again at the library code, to see if there was anything wrong with it. Wanting to optimise the library as much as possible, I'd declared all the functions 'inline'. Removed these modifiers and Presto! Library now works.
Kind of understand why inlining would cause a linker error - it wouldn't be able to insert the code at compile time or something...? But does this mean that library functions can't be declared inline? And aren't some member functions automatically inlined?
Glad to have finally fixed it though, and thanks to dwise1_aol and 3dfxMM for making helpful suggestions!
Practise Random Kindness
April 29th, 2003, 07:03 PM
Yes, I would think that a library function intended to be accessible to another module could not be declared as inline. However, you should be able to make some functions inline as long as you write the function body in the header file. There have been some heated discussion here about not putting code into the header file, but in the case of inline functions it's not only proper, but even necessary.
Actually, I had been taught to put inline functions in the header file. Had you declared them as inline in the header and then put the body in the .cpp file? Yeah, I think that would definitely make them inaccessible to the other module.
Glad you solved your problem.