views:

662

answers:

4

Hi. I'm trying to build a project in Visual Studio 2008. I'm getting a bunch of linker errors that are really bothering me. My application is a Win32 console application using only native ANSI C++.

They are all linker errors of the same pattern. Linker errors are related to every single private static data member of classes I have defined in my own header files.

I'm guessing this is probably a simple fact of c++ I'm not already aware of?

Example: I refer to the members of SingleDelay within function definitions of SingleDelay's member classes in a file Delays.cpp. ie:

SingleDelay::tick(void *output, void *input, int nbufferFrames)
{ //.. code here
x = dry * castInput + wet * castInput;
}

Error 38 error LNK2001: unresolved external symbol "private: static double SingleDelay::dry" (?dry@SingleDelay@@0NA) Delays.obj testall

Definition of SingleDelay in Delays.h:

class SingleDelay{

    private:  
        static double dry; //% of dry signal<br>
        static double wet; //% of wet signal<br>
        static unsigned int delay; //Delay in milliseconds<br>
        static int delayCell; //Index in the delayBuffer of the delay to add<br>
        static double *delayBuffer; //Delay buffer is 1 second long at sample rate SAMPLE_RATE<br>
        static unsigned int bufferCell; //Pointer to the current delay buffer cell<br>

    public:

        //Tick function
        static void tick(void *output, void *input,int nBufferFrames);

        //Set and Get functions
        static void setSingleDelay(double tDry, double tWet, unsigned int tDelay);
        static void setSingleDelay(void);

        static void setDry(double tDry);
        static void setWet(double tWet);
        static void setDelay(unsigned int tDelay);

        static double getDry(){ return dry;}
        static double getWet(){ return wet;}
        static unsigned int getDelay(){ return delay;}

        static void initializeDelayBuffer(){
            destroyDelayBuffer();

            delayBuffer = new double[bufferLength];
        }
        static void destroyDelayBuffer(){
            delete[ ] delayBuffer;
        }
};
A: 

Are you adding the .cpp and .h files to .vcproj file?

Vinay
i'm not sure what that means. I don't manually edit my .vcproj files with a text editor or anything. I have dragged and dropped all the necessary include files into the header files drop down menu in the Solution Explorer for my project. I also put *.cpp files that I can find in Source Files menu.
Rich
I checked and I was in fact missing some .cpp files that seemed to clear up most of my linker errors for #2. I'm still not sure about what to do with all the #1 type linker errors I still get.
Rich
Goto Project->Add Files and then select the .cpp and .h instead of dragging and dropping.
Vinay
+2  A: 
  1. Maybe you haven't added the library and include paths of the library you use to the project definitions?
  2. C++ error are always fun to look at. Or not. In any case, do you initialize your static variables anywhere? You need to do this in a .cpp file somewhere. And remember to use static variables with care. They are actually global variables in disguise, and can make future changes, such as multi-threading, more difficult.
Gilad Naor
2. Yea I thought it would be the initialization of the static variables that caused the problem. Must that be done in a .cpp or can I do it after the class definition in the .h file? The initialized values will really be overwritten when I actually use the class, so they aren't very important to me.
Rich
As for using static, I made all my delay classes static because, for my purposes, the user is only using one of each and only one at a time, so instantiating the class seemed superfluous and might have actually been giving me troubles in its own that I avoided by going static.
Rich
Okay, I tried to initialize the variables again and it worked this time. Seemed I was making some small mistakes the first go around. Thanks for the help everyone, sometimes it takes others to push you to try the same thing twice =).
Rich
Good luck!!!You may want to check this link:http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.11Also read the item below it, because the order of initializing static variables is undefined, and can create random problems if you're not careful.
Gilad Naor
Please, do check the answer by greyfade, as it is the correct one. When you define the static attributes in the header you are not reserving memory for it, just declaring the variable (similar to an extern declaration). You must declare the variables in one compilation unit.
David Rodríguez - dribeas
+5  A: 

They are all linker errors of the same pattern. Linker errors are related to every single private static data member of classes I have defined in my own header files.

All static data members must have a definition in a .cpp file somewhere.

Error 38 error LNK2001: unresolved external symbol "private: static double SingleDelay::dry" (?dry@SingleDelay@@0NA) Delays.obj testall

The linker is telling you that there is no defined storage for that variable. This line must appear somewhere in exactly one .cpp file:

double SingleDelay::dry = 0.0;
greyfade
A: 

Hi, Jun!

Maybe error consists in your static fields visibility scope, because they are private. Try write code that use your privete static field in class definition, not beyond your class. Write this method just in your class definition:

class SingleDelay{
 ...
int tick(void *output, void *input, int nbufferFrames)
{ //.. code here
x = dry * castInput + wet * castInput;
}
 ...
}
Roman