我有一个应用程序需要设置库将用于报告信息的日志回调。我最初是静态编译我的库,但现在我需要将它用作dll。当我的应用程序调用函数来测试失败条件时,库应该使用回调记录函数失败的原因。这在静态链接时没有问题,但在动态链接时会导致分段错误。这个函数在调用函数时会立即发生,我无法进入日志记录回调。
我的应用程序能够调用dll中定义的API函数,它是dll函数,一旦尝试调用日志回调就会导致错误。当我使用库中内置的存根函数并且应用程序不尝试使用自定义回调时,甚至会发生这种情况。
我的库是用C语言编写的,应用程序是使用Qt的C ++ GUI。我使用Qt Creator构建我的库(MinGW),但我的库不使用Qt库中的任何东西。
以下是我的日志回调类型的定义:
typedef void __attribute__((cdecl)) LogFn(char const * const fname, unsigned int const line, LogLvl const level, unsigned long long const time, Err const err, char const * const reason);
这是我的日志记录功能的声明和示例调用,它是库的全局:
LogFn * DebugLogFn = LogDflt;
DebugLogFn(LOG_FNAME, __LINE__, LOG_WARN_ENUM, CurTime(), ERR_X_ENUM, "something");
LogDflt是库在应用程序指定自定义回调之前使用的存根函数:
void __attribute__((cdecl)) LogDflt(char const * const fname, unsigned int const line, LogLvl const level, unsigned long long const time, Err const err, char const * const reason) {
// do nothing
}
当我静态链接时,即使将回调设置为我的某个应用程序类的静态函数,它也能正常工作。
此外,只要我没有将错误输入传递给dll函数,应用程序将在动态链接时完全正常执行,因为这会导致它尝试调用日志函数。
堆栈追踪:
0 ??
1 test_create_destroy Test.c 225 0x40aaec
2 Test::run test.cpp 70 0x40408f
3 QThreadPrivate::start(void*)*4 407 0x6b798b92
4 msvcrt!_itow_s C:\Windows\syswow64\msvcrt.dll 0x75551287
5 msvcrt!_endthreadex C:\Windows\syswow64\msvcrt.dll 0x75551328
6 KERNEL32!BaseThreadInitThunk C:\Windows\syswow64\kernel32.dll 0x75cd337a
7 ntdll!RtlInitializeExceptionChain C:\Windows\system32\ntdll.dll 0x777d92e2
8 ntdll!RtlInitializeExceptionChain C:\Windows\system32\ntdll.dll 0x777d92b5
9 ??