如何检测功能是否在已安装的库中实现?
How to detect if function is implemented in installed library?
我有我的 windows 程序,它使用 windows 系统库(我们将其命名为 "sysLib"
),它实现了函数 "libFun1"
。我的程序可以是这样的:
#include <sysLib.h>
void myFunction() {
//some magic here
}
int main() {
myFunction();
libFun1();
return 0;
}
稍后,库得到更新,其中添加了新的 "libFun2"
函数,它完美地完成了我的 "myFunction"
所做的,甚至做得更好。所以我将程序更新为如下所示:
#include <sysLib.h>
int main() {
libFun2();
libFun1();
return 0;
}
我编译它并推送更新给客户端。
但是有一些客户,他们没有最新版本的 windows 并且他们有旧版本的 "sysLib"
没有实现 "libFun2"
,所以他们的程序不起作用(甚至没有开始)。
我发现,如果我用 "delayimp.lib /DELAYLOAD:sysLib.dll"
编译我的程序,程序现在可以启动,但在调用 "libFun2"
时下降。
我现在想更新我的代码,使其看起来像这样:
#include <sysLib.h>
void myFunction() {
//some magic here
}
int main() {
if(/*libFun2 exists*/) {
libFun2();
} else {
myFunction();
}
libFun1();
return 0;
}
如果 "libFun2"
函数存在于库中并围绕它制定逻辑,我如何检测?
I know that in linux is possible to do if(libFun2)
, but this doesn't work in windows
更新:
我发现,它可以被__try __except组合捕获,但它对我不起作用...
https://docs.microsoft.com/en-us/cpp/build/reference/error-handling-and-notification?view=msvc-170
bool hasExport(LPCSTR mod, LPCSTR func)
{
HMODULE handle = LoadLibraryA(mod);
return handle && GetProcAddress(handle, func);
}
...
if (hasExport("syslib", "libfun2"))
libfun2(); // must be delay loaded
else
...
此代码假定您不需要再次卸载库。它也不关心库是否已经加载。如果您需要不同的行为,请使用 GetModuleHandle
或 FreeLibrary
。
在这种特定情况下,由于您有一个替换函数,您可以改为使用延迟加载挂钩并通过返回回退函数来处理 dliFailGetProc
。
解决方法很简单:
#include <sysLib.h>
#include <delayimp.h>
int CheckDelayException(int exception_value)
{
if (exception_value == VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND) ||
exception_value == VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND))
{
// This example just executes the handler.
return EXCEPTION_EXECUTE_HANDLER;
}
// Don't attempt to handle other errors
return EXCEPTION_CONTINUE_SEARCH;
}
void myFunction() {
__try {
libFun2();
return;
} __except (CheckDelayException(GetExceptionCode())) {
myFunction();
}
//some magic here
}
int main() {
myFunction();
libFun1();
return 0;
}
https://docs.microsoft.com/en-us/cpp/build/reference/error-handling-and-notification?view=msvc-170
UPDATE: moved __try into function for better usage in code, if multiple calls are used
我有我的 windows 程序,它使用 windows 系统库(我们将其命名为 "sysLib"
),它实现了函数 "libFun1"
。我的程序可以是这样的:
#include <sysLib.h>
void myFunction() {
//some magic here
}
int main() {
myFunction();
libFun1();
return 0;
}
稍后,库得到更新,其中添加了新的 "libFun2"
函数,它完美地完成了我的 "myFunction"
所做的,甚至做得更好。所以我将程序更新为如下所示:
#include <sysLib.h>
int main() {
libFun2();
libFun1();
return 0;
}
我编译它并推送更新给客户端。
但是有一些客户,他们没有最新版本的 windows 并且他们有旧版本的 "sysLib"
没有实现 "libFun2"
,所以他们的程序不起作用(甚至没有开始)。
我发现,如果我用 "delayimp.lib /DELAYLOAD:sysLib.dll"
编译我的程序,程序现在可以启动,但在调用 "libFun2"
时下降。
我现在想更新我的代码,使其看起来像这样:
#include <sysLib.h>
void myFunction() {
//some magic here
}
int main() {
if(/*libFun2 exists*/) {
libFun2();
} else {
myFunction();
}
libFun1();
return 0;
}
如果 "libFun2"
函数存在于库中并围绕它制定逻辑,我如何检测?
I know that in linux is possible to do
if(libFun2)
, but this doesn't work in windows
更新:
我发现,它可以被__try __except组合捕获,但它对我不起作用...
https://docs.microsoft.com/en-us/cpp/build/reference/error-handling-and-notification?view=msvc-170
bool hasExport(LPCSTR mod, LPCSTR func)
{
HMODULE handle = LoadLibraryA(mod);
return handle && GetProcAddress(handle, func);
}
...
if (hasExport("syslib", "libfun2"))
libfun2(); // must be delay loaded
else
...
此代码假定您不需要再次卸载库。它也不关心库是否已经加载。如果您需要不同的行为,请使用 GetModuleHandle
或 FreeLibrary
。
在这种特定情况下,由于您有一个替换函数,您可以改为使用延迟加载挂钩并通过返回回退函数来处理 dliFailGetProc
。
解决方法很简单:
#include <sysLib.h>
#include <delayimp.h>
int CheckDelayException(int exception_value)
{
if (exception_value == VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND) ||
exception_value == VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND))
{
// This example just executes the handler.
return EXCEPTION_EXECUTE_HANDLER;
}
// Don't attempt to handle other errors
return EXCEPTION_CONTINUE_SEARCH;
}
void myFunction() {
__try {
libFun2();
return;
} __except (CheckDelayException(GetExceptionCode())) {
myFunction();
}
//some magic here
}
int main() {
myFunction();
libFun1();
return 0;
}
https://docs.microsoft.com/en-us/cpp/build/reference/error-handling-and-notification?view=msvc-170
UPDATE: moved __try into function for better usage in code, if multiple calls are used