Home > OS >  How to detect if function is implemented in installed library?
How to detect if function is implemented in installed library?

Time:04-14

I have my program for windows, which uses windows system library (let's name it "sysLib"), and it implements function "libFun1". My program can look like this:

#include <sysLib.h>

void myFunction() {
    //some magic here
}

int main() {
    myFunction();
    libFun1();
    return 0;
}

later, library gets update, in which new "libFun2" function is added and it perfectly does what my "myFunction" do and even does it better. So I update my program to look like this:

#include <sysLib.h>

int main() {
    libFun2();
    libFun1();
    return 0;
}

I compile it and push update to clients.

But there are some clients, who doesn't have last version of windows and they have the old version of "sysLib" which doesn't implement "libFun2", so program for them doesn't work (doesn't even start).

I figured out, that if i compile my program with "delayimp.lib /DELAYLOAD:sysLib.dll", program is now startable, but falls when "libFun2" is called.

I would like to now update my code to looku something like this:

#include <sysLib.h>

void myFunction() {
    //some magic here
}

int main() {
    if(/*libFun2 exists*/) {
         libFun2();
    } else {
         myFunction();
    }
    libFun1();
    return 0;
}

How can i detect, if "libFun2" function exists inside library and make logic around it?

I know that in linux is possible to do if(libFun2), but this doesn't work in windows

UPDATE:

I found out, that it can be catched by __try __except combination, but it doesnt work for me...

https://docs.microsoft.com/en-us/cpp/build/reference/error-handling-and-notification?view=msvc-170

CodePudding user response:

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
  ...

This code assumes that you don't need to unload the library again. It also does not care if the library was already loaded. Use GetModuleHandle or FreeLibrary if you need a different behavior.

In this specific case, since you have a replacement function you could instead use a delayload hook and handle dliFailGetProc by returning the fallback function.

CodePudding user response:

Solution is pretty simple:

#include <sysLib.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() {
    //some magic here
}

int main() {
    try {
         libFun2();
    } __except (CheckDelayException(GetExceptionCode())) {
         myFunction();
    }
    libFun1();
    return 0;
}

https://docs.microsoft.com/en-us/cpp/build/reference/error-handling-and-notification?view=msvc-170

  • Related