Как решить функцию, действующую по-разному в зависимости от места вызова? - PullRequest
4 голосов
/ 24 мая 2019

Не знаю, как произнести название, так что не стесняйтесь переименовывать, но у меня проблема в том, что у меня есть функция, которая работает в одном проекте, но не работает в другом. Ниже приведен приблизительный псевдокод, показывающий, что один вызов в LibraryProject работает, а вызов в GameProject - нет.

В ChildClass::do_stuff, win32_window HWND действителен, тогда как второй, failed_win32_window равен нулю, и glfw выдает ошибку, говоря, что она не инициализирована, несмотря на то, что она уже была инициализирована (так как первый вызов glfw был успешным и я вручную прошел, чтобы убедиться, что это было):

GLFWError #65537 Happen, The GLFW library is not initialized

Вот псевдокод, показывающий два проекта и файлы. GLFW настроен правильно, поскольку, если я выполняю всю свою логику glfw в LibraryProject, окно отображается как обычно.

//LibraryProject

////library_header.h
class ParentClass {
  GLFW* _mainWindow; //filled in elsewhere in the real code
  HWND getWin32Window() { return glfwGetWin32Window(_mainWindow); }
}

//GameProject

////game_header.h
#include "library_header.h" //from other Project

class ChildClass : public ParentClass {
  void do_stuff() {
    HWND win32_window = this->getWin32Window(); //this works because it goes down into LibraryProject.dll's module
    HWND failed_win32_window = glfwGetWin32Window(_mainWindow); //but literally the same call here doesn't because it happens within GameProject.exe
  }
}

////game_body.cpp

void function_called_elsewhere_in_game() {
    //called from GameProject.exe
    auto child = ChildClass();
    child.do_stuff();
}

Я не уверен, что это проблема с glfw и моей настройкой, или просто мое недопонимание того, как работают проекты и зависимости.

Вещи, которые я пробовал:

  • Загрузка последней glfw3
  • Перестройка всего решения
  • Переключение со ссылками и связывание входов зависимостей

На что обратить внимание:

  • Это происходит в главном потоке, больше ничего не использует в то же время glfw. Его 100% воспроизводимость тоже.
  • glfw3.lib всегда создается в моей выходной папке GameProject, на основе той, которая находится внутри LibraryProject
  • При выполнении разборки для каждого из двух вызовов glfwGetWin32Window в разборке используются разные адреса, что позволяет мне считать, что это две разные копии одной и той же библиотеки, но я не уверен.
  • Это не проблема с cocos2d, игровой движок, который я использую для запуска пустого проекта и вызова glfwGetWin32Window(..), возвращает верный указатель, даже в GameProject, поэтому я что-то делаю не так, но я не не знаю что.

Изображения, демонстрирующие реальное поведение. magnolia_cocos_proj - это GameProject и исполняемый файл, который я запускаю, а libcocos2d - это LibraryProject, который я использую в качестве DLL (я не знаком с подробностями работы ссылок и dll).

  1. win32_window имеет допустимое значение
  2. определение getWin32Window () для 100% уверенности . Обратите внимание, что модуль находится в libcocos2d.dll сейчас.
  3. после перехода через вторую строку выдается ошибка, и второе окно становится пустым

Ответы [ 2 ]

3 голосов
/ 29 мая 2019

Как я понял из "glfw3.lib всегда создается", вы используете статическое связывание. Статическое связывание библиотеки с различными dll и exe приводит к дублированию всей статической памяти библиотеки. Вы должны использовать динамическую библиотеку для GLFW в этом случае. Это glfw3dll.lib.

2 голосов
/ 02 июня 2019

Существует два основных случая возникновения этой ошибки:

GLFWError #65537 Happen, The GLFW library is not initialised

Дело 1 :

Указанная ошибка возникает, если была вызвана функция GLFW, которую нельзя вызывать, пока библиотека не инициализирована. So, you need to initialise GLFW before calling any function that requires initialisation.

Прочитайте введение API для справки. Используйте оператор if-else для обработки glfwInit() и ошибок.

Чтение Переход от GLFW 2 к 3 также полезен.

Дело Два :

Эта ошибка довольно часто возникает в том случае, если на вашем компьютере установлены предыдущие версии GLFW. GLFW3 не любит работать вместе с предыдущей установленной версией. So, delete all the GLFW libraries and linkers and reinstall the latest GLFW 3 from scratch.

Надеюсь, это поможет.

...