Error 2019

The problem is that I get error 2019, but I don't know what's wrong. I searched about it and I found that it can mean a lot of things. I use visual studio 2013 and the error is:

error LNK2019: unresolved external symbol "public: __thiscall imaging::Image::Image(unsigned int,unsigned int,float const *)" (??0Image@imaging@@QAE@IIPBM@Z) referenced in function "class imaging::Image * __cdecl imaging::ReadPPM(char const *)" (?ReadPPM@imaging@@YAPAVImage@1@PBD@Z)	
C:\Users\John\documents\visual studio 2013\Projects\Ergasia1\Ergasia1\ppm_format.obj	
Ergasia1 (this is the name of the project, it's greek word with english characters. don't get confused)


Someone told my that I call Image constructor with wrong arguments. The project reads a .ppm file(a photo file) and creates an image object which contains the dimentions and the pixels. If the problem is the way I call the constructor, which is the right way to call it? Thanks in advance.

(the following code is contained in the ReadPPM method, which is contained in the ppm_format.cpp file, reads the .ppm file and then creates the Image object)
1
2
3
4
5
6
7
8
9
10
11
imaging::Image * newimage;

unsigned char *datachar;
float *datafloat;

datachar = new unsigned char[size]; //I save the data of the .ppm file here
datafloat = new float[size2];       //I translate chars to float, so I can get the actual number(float) of each pixel component

newimage = new Image(width, height, datafloat); //I call the Image constructor. Probably here is where the error comes from

return newimage;



(here are the the constructors, destructor etc of Image class. There are other methods too. component_t variable type comes from typedef float component_t)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

enum channel_t { RED = 0, GREEN, BLUE };

component_t * buffer;

Image() : width(0), height(0), buffer(nullptr){}		
Image(unsigned int _width, unsigned int _height){
	width = _width;
	height = _height;
}
Image(unsigned int _width, unsigned int _height, const component_t * data_ptr){
	width = _width;
	height = _height;
	*buffer = *data_ptr;
}
Image(const Image &src) :width(src.width), height(src.height), buffer(src.buffer){}
~Image(){
        delete[] buffer;
}
Image & operator = (const Image & right){
	Image left = Image(right);
	return left;
}


(code in main.cpp. This is where I call ReadPPM to read the .ppm file and create the Image object)
1
2
string file = "Image01.ppm";
Image * image = ReadPPM(file.c_str());
Last edited on
error LNK2019: unresolved external symbol

This means that the linker can't find the implementation for the function that is indicated, in this case: imaging::Image::Image(unsigned int,unsigned int,float const *).

So it looks like you haven't declared a constructor of the Image class that takes an unsigned int, unsigned int, and a float *.


Last edited on
I think this is the third constructor(the one with the tree arguments). Am I wrong?
Am I wrong?

Probably. Is the last parameter in that constructor a float*?

Yes it is. The fact is that if I use any Image constructor, I get the same error, so I think I do something wrong in the definition or decleration of Image class. I changed it since last post. Now I call the constructor like this:
(this code is contained is ReadPPM method in ppm_format.cpp)
imaging::Image * newimage = new imaging::Image();
Please check my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#ifndef _IMAGE
#define _IMAGE

#include "Color.h"

// We put every class or function associated with the image storage, compression and manipulation 
// in the "imaging" namespace
namespace imaging
{


//------------------------------------ class Image ------------------------------------------------
// 
// It is the class that represents a generic data container for an image. It holds the actual buffer
// of the pixel values and provides methods for accessing them either as individual pixels or as
// a memory block. The Image class alone does not provide any functionality for loading and storing an image, as
// it is the result or input to such a procedure. 
//
// The internal buffer of an image object stores the actual bytes (data) of the color image as
// a contiguous sequence of RGB triplets. Hence, the size of the buffer variable holding these data is 
// 3 X width X height bytes.

	class Image
	{
	public:
		enum channel_t {RED=0,GREEN, BLUE};          // now you can use the names RED, GREEN, BLUE instead of 0,1,2
		                                             // to index individual channels
	protected:
		component_t * buffer;                        // Holds the image data

		unsigned int width, height;                  // width and height of the image (in pixels)

	public:
		// metric accessors
		const unsigned int getWidth() const {return width;}      // returns the width of the image
		const unsigned int getHeight() const {return height;}    // returns the height of the image

		// data accessors
		component_t * getRawDataPtr();                           // Obtain a pointer to the internal data
		                                                         // This is NOT a copy of the internal image data, but rather 
		                                                         // a pointer to the internally allocated space, so DO NOT
		                                                         // attempt to delete the pointer. 

		Color getPixel(unsigned int x, unsigned int y) const;    // get the color of the image at location (x,y)
		                                                         // Do any necessary bound checking. Also take into account
		                                                         // the "interleaved" flag to fetch the appropriate data
		                                                         // Return a black (0,0,0) color in case of an out-of-bounds
		                                                         // x,y pair

		// data mutators
		void setPixel(unsigned int x, unsigned int y, Color & value); 
		                                                         // Set the RGB values for an (x,y) pixel. Do all 
		                                                         // necessary bound checks and respect the "interleaved"
		                                                         // flag when updating our data.

		void setData(const component_t * & data_ptr);            // Copy the data from data_ptr to the internal buffer.
		                                                         // The function ASSUMES a proper size for the incomming data array.

		void resize(unsigned int new_width, unsigned int new_height);
		                                                         // Change the internal data storage size to the new ones.
		                                                         // If the one or both of the dimensions are smaller, clip the 
		                                                         // by discarding the remaining pixels in the rows / columns outside
		                                                         // the margins. If the new dimensions are larger, pad the old pixels
		                                                         // with zero values (black color).

		// constructors and destructor
		Image();											     // default: zero dimensions, nullptr for the buffer.	
		Image(unsigned int _width, unsigned int _height);
		Image(unsigned int _width, unsigned int _height, const component_t * data_ptr);
		Image(const Image &src);
		~Image();

		Image & operator = (const Image & right);

	};

} //namespace imaging

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
#include "Image.h"
#include "Color.h"

using namespace std;
using namespace imaging;
class Image{
	
	public:
		enum channel_t { RED = 0, GREEN, BLUE };  
	protected:
		component_t * buffer;	

		unsigned int width, height;    
	public:

		const unsigned int getWidth() const { return width; }
		const unsigned int getHeight() const { return height; }

		component_t * getRawDataPtr(){
			return buffer;
		}

		Color getPixel(unsigned int x, unsigned int y) const{
			Color color;
			if ((x <= width) && (y <= height) && (x*y >= 0)){
				color[RED] = x*y;
				color[GREEN] = x*y + GREEN;
				color[BLUE] = x*y + BLUE;
			}
			return color;
		}

		void setPixel(unsigned int x, unsigned int y, Color & value){
			if ((x <= width) && (y <= height) && (x*y >= 0)){
				buffer[x * y + RED] = value[RED];
				buffer[x * y + GREEN] = value[GREEN];
				buffer[x * y + BLUE] = value[BLUE];
			}
			else{
				cout << "Width or heigth out of bounds!" << endl;
			}
		}

		void setData(const component_t * & data_ptr){
			int size = 3 * width * height;
			buffer = new component_t[size];

			for (int i = 0; i < size; i++){
				buffer[i] = data_ptr[i];
			}
		}

		void resize(unsigned int new_width, unsigned int new_height){
			/*to be filled!!!*/
		}

		Image() : width(0), height(0), buffer(nullptr){}		
		Image(unsigned int _width, unsigned int _height) : width(0), height(0), buffer(nullptr){
			width = _width;
			height = _height;
		}
		Image(unsigned int _width, unsigned int _height, const component_t * data_ptr) : width(0), height(0), buffer(nullptr){
			width = _width;
			height = _height;
			setData(data_ptr);
		}
		Image(const Image &src) :width(src.width), height(src.height), buffer(src.buffer){}
		~Image(){
			delete[] buffer;
		}

		Image & operator = (const Image & right){
			Image left = Image(right);
			return left;
		}

};

Last edited on
Btw, I use the namespace imaging. I use it like this:
in ppm_format.h, Image.h and Color.h I do:
1
2
3
namespace imaging{
     //ReadPPM declaration
}


in ppm_format.cpp, Image.cpp, Color.cpp and main.cpp I do:
 
using namespace imaging;


and I also get this error:
error LNK2019: unresolved external symbol "class imaging::Image * __cdecl imaging::ReadPPM(char const *)" (?ReadPPM@imaging@@YAPAVImage@1@PBD@Z) referenced in function _main
C:\Users\John\documents\visual studio 2013\Projects\Ergasia1\Ergasia1\main.obj
Ergasia1
Yes it is.

It looks like a component_t type to me. Where is this component_t type defined?

What exactly is that second snippet? If it is not an inadvertent double post then that code is probably a big part of the problem because both of these snippets are trying to declare an Image class.
component_t is float. Typedef for this is in Color.h. Finally solved it. I tried to declare Image two times, as you said. Thank you for your time and for your help!!!
Then in your first post datafloat should probably be a component_t type not a float. If you're going to use typedefs use them everywhere.
Topic archived. No new replies allowed.