我将从我的项目结构开始。我静态将freeglut链接到共享库,其中我有键盘回调:
// DECLARATION
TW_API int twKeyCallbackGLUT_d (unsigned char key, int mouseX, int mouseY);
// DEFINITION
int TwEventKeyboardGLUT(unsigned char glutKey, int mouseX, int mouseY)
{
int kmod = 0;
int glutMod = glutGetModifiers();
if( glutMod&GLUT_ACTIVE_SHIFT )
kmod |= TW_KMOD_SHIFT;
if( glutMod&GLUT_ACTIVE_CTRL )
kmod |= TW_KMOD_CTRL;
if( glutMod&GLUT_ACTIVE_ALT )
kmod |= TW_KMOD_ALT;
if( (kmod&TW_KMOD_CTRL) && (glutKey>0 && glutKey<27) ) // CTRL special case
glutKey += 'a'-1;
return TwKeyPressed((int)glutKey, kmod);
}
TW_API int twKeyCallbackGLUT_d(unsigned char key, int mouseX, int mouseY) {
return TwEventKeyboardGLUT(key, mouseX, mouseY);
}
然后,我将该库链接到我的可执行文件,我使用以下代码:
void onKeyboardKey(unsigned char key, int mouseX, int mouseY)
{
// send event to AntTweakBar
if (twKeyCallbackGLUT_d(key, mouseX, mouseY))
glutPostRedisplay(); // request redraw if event has been handled
}
int main(int argc, char *argv[])
{
// Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutCreateWindow("AntTweakBar string example");
glutCreateMenu(NULL);
glutGetModifiers(); // test line
// Set GLUT callbacks
glutDisplayFunc(OnDisplay);
glutReshapeFunc(OnReshape);
std::atexit(onTerminate); // Called after glutMainLoop ends
// Initialize AntTweakBar
TwInit(TW_OPENGL, NULL);
// Set events callbacks:
glutMotionFunc(onMouseMotion);
glutPassiveMotionFunc(onMouseMotion);
glutMouseFunc(onMouseButton);
glutKeyboardFunc(onKeyboardKey);
...
}
问题是当程序在库回调中遇到glutGetModifiers()时我得到了#34;错误:调用函数时没有先调用&#39; glutInit&#39;。&#34;和https://github.com/dcnieho/FreeGLUT/blob/FG_3_0_0/src/fg_state.c#L298引起的应用程序退出,但我正如你所见,正在我的main()内正确调用glutInit。主要glutGetModifiers(); // test line
不会导致此错误。
请注意,应用程序运行成功并且所有回调都能正常工作(例如鼠标回调),当我按任意键盘键时应用程序失败,因为键回调是唯一一个使用glut方法的回调。我发现当我进入库方法时,范围fgState.Initialised
(freeglut的变量,如果调用了glutInit则为true)等于0,但是我的可执行范围等于1。
当我决定检查其他构建系统时出现最奇怪的事情,因为我使用Cmake,我为MinGW配置了项目并且成功构建,glutGetModifiers()调用没有错误发生,只有VS2015导致它
我检查的最后一件事是线程,我认为我的库出于某种原因使用另一个线程进行回调(或者VS创建其他线程),但事实并非如此,所有应用程序都包含在一个线程中。
有人可以向我解释,为什么这个错误出现在VS上并且没有出现在MinGW构建中,这让我很困惑〜
UPD1:我做了导致问题的项目的最小示例https://gist.github.com/Liastre/97dc12c01da097406cbf5beecada474c
UPD2:我的库的静态链接不会导致问题(因为在这种情况下,freeglut应该直接链接到可执行文件),所以当freeglut没有直接链接到可执行文件时会出现问题