m_smith Ответов: 3

Неразрешенный внешний символ - функция не видит определения [SOLVED]


Ошибку lnk2019 неразрешенный внешний символ "общественности: __thiscall дисплей: дисплей:Дисплей(ничтожным)" (??0display@@ка@ХZ), на которые ссылается функция "общественности: __thiscall поля: поле(ничтожным)" (??0field@@ка@ХZ) SnakeByteWin C:\Users\iptamas\source\repos\SnakeByteWin\SnakeByteWin\field.obj 1

Ошибку lnk2019 неразрешенный внешний символ "общественности: пустота __thiscall дисплей::displayFullGame(структура его hwnd__ *,класс поле *,тип int)" (?displayFullGame@дисплея@@QAEXPAUHWND__@@PAVfield@@н@з), на которые ссылается функция "длинный __WindowProci нарушением соглашения о стандартном(структура его hwnd__ *,беззнаковый тип int без знака int,длинные)" (?WindowProci@@YGJPAUHWND__@@IIJ@з) SnakeByteWin C:\Users\iptamas\source\repos\SnakeByteWin\SnakeByteWin\windowproc.obj 1

Всем Привет,
Это ошибка, которую я постоянно получаю. У меня есть поле.ч с поле класс, дисплей.ч с дисплейным классом, и процедуре windowproc.ч и .СРР с помощью функции windowproc. Я предполагаю, что windowproc не может видеть определение класса отображения, но я не знаю почему.
поле.h=========================================
#ifndef FIELD_H_INCLUDED
#define FIELD_H_INCLUDED

#include "defines.h"
#include "matrix.h"
#include "bites.h"
#include "snake.h"
#include "display.h"

class field {
      int score;
      int hiScore;
      int level;
      int nofBites;
      int speed;
      int scoreCounter;
      bool isGameOn;
      bites* bitesPr;
      snake* snakePr;
      matrix* matrixPr;
      display* displayPr;
   public:
      field();
      ~field();
      void initLevel();
      void initGame();
      int getScore();

void setScore(int);........ и так далее....
дисплей.h=========================================
#pragma once
#include"windowproc.h"
class field;
class display {
		HBITMAP hBitmapWall;
		HBITMAP hBitmapNoWall;
		HBITMAP hBitmapBites;
		HBITMAP hBitmapSnake;
		HBITMAP hBitmapStartButton;
		RECT scoreRect;
	public:
		display();
		BOOL CALLBACK displayChildWindows(HWND hwnd, LPARAM lParam);
		void displayFullGame(HWND hwnd, field*, int);
		RECT getScoreRect();
		HBITMAP getBitmapWall();
		HBITMAP getBitmapNoWall();
		HBITMAP getBitmapBites();
		HBITMAP getBitmapSnake();
		HBITMAP getBitmapStartButton();
};

windowproc.cpp===============================================
#include "field.h"

LRESULT CALLBACK WindowProci(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
	LRESULT r = 0; 
	field* fg=(field*)GetWindowLongPtr(hwnd, GWLP_USERDATA);

	switch(uMsg){
		case WM_NCCREATE: {	
		SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG)(((CREATESTRUCT*)lParam)->lpCreateParams));	
		r=DefWindowProc(hwnd, uMsg, wParam, lParam);
		break;

		}
	...... other case's ......


		case WM_TIMER: {//=========================   WM_TIMER message  =====================
			//display d;
			if (!fg->getNofBites()) PostMessage(hwnd, STARTNEWLEVEL, 0, 0);			// events of fullGame + display fullGame
			fg->isSnakeAlive();
			fg->moveSnake();
			fg->decreaseScoreCounter();
			if (fg->isBitesEaten()) {
				fg->generatePositionBites();
				fg->nofBitesDown();
				fg->setScore(fg->getScore() + fg->getScoreCounter());
				fg->setScoreCounter(SCORECOUNTER + fg->getLevel()*LEVELLER);
				fg->getSnakePr()->setCounter(COUNTER);
				fg->getDisplayPr()->displayFullGame(hwnd, fg, DISPLAYSCORE);
			}
			fg->getDisplayPr()->displayFullGame(hwnd, fg, DISPLAYBITES);
			fg->getDisplayPr()->displayFullGame(hwnd, fg, DISPLAYSNAKE);
			if (fg->getSnakePr()->getAlive()) PostMessage(hwnd, GAMEOVER, 0, 0);				
			break;			
}// case WM_TIMER)


Что я уже пробовал:

Мое предположение состоит в том, что "include" не являются правильными. Я перепробовал почти все варианты, но когда мне удалось избежать всех "двойных включений", я все равно получил то же самое сообщение.
Я также попытался создать экземпляр класса display в функции windowproc, но это тоже не сработало.
Есть идеи? Спасибо.

RedDk

LNK2019 - это ошибка компоновщика. Компоновщик не может найти библиотеку, необходимую для функции или метода, используемого в коде, и ссылается на нее. Имена искажаются (все эти @@QAE ... (это же C++, в конце концов)) так что для того, чтобы узнать ... в какой момент начинается каскад несвязанных вещей ... попробуйте связать их с добавлением командной строки под названием /VERBOSE. Затем, когда компоновщик перечислит то, на что ссылаются, у вас будет точное место для проверки (см. список ссылок на библиотеки, которые вы связываете). Имя отсутствующей библиотеки, скорее всего, будет иметь расширение .lib.

Вы также можете выполнить общесистемный поиск для всех .файлы lib. Скорее всего, там, где они находятся, пропавший .lib должен быть/должен быть. Также погуглите приложение; я предполагаю, что вы ищете что-то со змеиным укусом в названии, да?

m_smith

Спасибо. Я могу тебя неправильно понять... Я проверил выходные данные и получил много "найденных" вещей в "referenced". libs, но сообщение об ошибке одно и то же. Когда он заканчивает проверку/поиск библиотек, сообщение просто "закончен поиск библиотек". И да, это змеиный укус, и он работает на консоли :)

3 Ответов

Рейтинг:
28

Jochen Arndt

Цитата:
Я предполагаю, что windowproc не может видеть определение класса отображения, но я не знаю почему.
Это действительно причина. Компилятор видит объявление display класс в дисплей.ч но определение (реализация) отсутствует. Я ожидал бы, что у вас также есть display.cpp файл. Если это так, то он также должен быть скомпилирован, и полученный объектный файл должен быть связан (например, просто добавив файл в свой проект).

Согласно первому сообщению об ошибке у вас есть поле.параметр obj файл, который, вероятно, был создан путем компиляции field.cpp. Вам нужно справиться с display класс в аналогичной манере.


m_smith

Спасибо, это ты! Я пытался решить эту проблему в течение нескольких дней, и на самом деле я просто забыл добавить display.cpp файл в проект. Какой позор! :)

Рейтинг:
2

KarstenK

Вы правы, что определение не может быть правильным решением, но решение заключается в использовании статических или глобальных функций и объектов.

static void displayFullGame(HWND hwnd, field*, int);

Это означает, что это не функция-член, а глобальная функция. Таким образом, возможно, вам следует использовать глобальный указатель на объект вашего класса и создавать и уничтожать его правильным образом.
display *gpDisplay = NULL;

Кстати: убедитесь, что вы реализовали конструктор
display::display() {
}


m_smith

Спасибо, Карстен, я хотел бы использовать его как функцию-член класса.

KarstenK

Это невозможно, потому что вход нуждается в некоторой статической функции. Вы можете использовать трюки, чтобы сделать это, но они могут нанести ответный удар и однажды разрушить вашу программу.

Рейтинг:
2

CPallini

Сообщение об ошибке ясно: где-то в вашем коде display ctor требуется, и вы не обеспечили реализацию. Вы должны либо:

  • Реализовать (в исходном коде) display::display()

или
  • Удалите объявление ctor в заголовочном файле (таким образом компилятор предоставит вам реализацию по умолчанию


m_smith

У меня тоже есть display.cpp-я дал там определение ctor. Извините, если я был недостаточно ясен.

#включить "display.h"

дисплей::Дисплей() {
scoreRect.left = 10;
scoreRect.top = 0;
scoreRect.right = 440;
scoreRect.bottom = 10;
}
...