Nilesh
Nilesh

Reputation: 624

Unable to call a pointer to function returning a pointer

I'm stuck with a weird problem. I have two files a.c and b.c as follows: b.c:

#include <stdlib.h>

int *foo() {
  int *x;
  x = (int *) malloc(sizeof(int));
  *x = 4;
  return x;
}

I compile b.c to b.so using gcc: $ gcc -o b.so -shared -fpic

a.c:

#include <stdio.h>
#include <dlfcn.h>

int main() {
  void *hdl;
  hdl = dlopen("./b.so", RTLD_LAZY);
  int *((*fn)(void));
  int *x;
  x = (*fn)();
  fn = dlsym(hdl, "foo");
  printf("%d", *x);
}

I compile a.c using gcc:

$ gcc -fpic -ldl a.c

Now when I run it:

$ ./a.out Segmentation fault

Where I'm I going wrong? This works when the function in b.c doesn't return a pointer.

And moreover, I tried checking for errors using dlerror(), but it reports none.

Upvotes: 3

Views: 226

Answers (4)

Beta
Beta

Reputation: 99172

By inspection, you are using fn before you have initialized it. It doesn't yet point to foo, it doesn't yet point to anything in particular, and I suspect the resultant behavior is undefined.

Upvotes: 6

Laurence Gonsalves
Laurence Gonsalves

Reputation: 143314

These two lines appear to be in the wrong order:

x = (*fn)();
fn = dlsym(hdl, "foo");

Upvotes: 3

Praveen S
Praveen S

Reputation: 10393

You are not finding the symbol and calling the function.

When you do x = (*fn)(); it doesnt make call to the function foo from b.c.

You have to first get the symbol loaded into your function pointer.

  int *x;
  fn = dlsym(hdl, "foo");
  x = fn();
  printf("%d", *x);

The above should work.

EDIT:

Sample program for dlopen,dlsym can be found here with man page info for the same.

Upvotes: 4

ronys
ronys

Reputation: 518

Could be just a problem with your example, but in the code you provide, you need to switch the following lines:

 x = (*fn)();
fn = dlsym(hdl, "foo");

Upvotes: 3

Related Questions