2

In C99 is there an easier way of check if a structure of function pointers is NULL, other than checking each individual pointer?

What I currently have is similar to the following:

typedef struct {
    void* (*foo)(int a);
    int   (*bar)(int a, int b);
} funcs;

void *funcs_dll;

funcs_dll = dlopen("my_funcs_dll.so", RTLD_GLOBAL);
if (funcs_dll == NULL) {
    THROW_ERROR;
}

funs.foo = dlsym(funcs_dll, "foo");
funcs.bar = dlsym(funcs_dll, "bar");

if (!funcs.foo || !funcs.bar) {
    THROW_ERROR;
}

What I am looking to do is reduce the second if check, so that I do not need to check each individual function. Any suggestions would be helpful.

slagathor
  • 302
  • 3
  • 12
  • Take a look at [this answer](http://stackoverflow.com/a/2589876/2703418). – bzeaman Dec 09 '14 at 14:25
  • Although the code is not formally well-defined behavior, [this example answers the question to 100%](http://stackoverflow.com/questions/8696653/dynamically-load-a-function-from-a-dll/23763255#23763255). – Lundin Dec 09 '14 at 14:27

2 Answers2

0

Make wrapper function for dlsym which will set error flag, if return value is NULL.

user694733
  • 15,208
  • 2
  • 42
  • 68
0

Not directly, no.

You can't use memcmp() to compare to some constant buffer, since there might be padding inside the structure which will have "random" values. If you can make sure that the size of the structure is exactly the sum of the function pointer fields, you can perhaps go that way.

You can also use a proxy, by i.e. declaring an initial uint32_t member that is a bitset representing which function pointer(s) are valid. Then you can check up to 32 (or 64 with uint64_t) proxy bits in parallel.

If you only want to do this once, my suggestion would be a data-driven approach. Define a table of function names to look for, and process that in a loop, exiting as soon as a dlsym() call fails.

Something like:

const struct {
  const char *name;
  size_t     offset;
} functions[] = {
{ "foo", offsetof(funcs, foo) },
{ "bar", offsetof(funcs, bar) },
};

Data-driven code like this is very powerful, and often very fast.

unwind
  • 391,730
  • 64
  • 469
  • 606