简体   繁体   中英

Use of shared library is good in c but same code is bad in c++?

Hi i have some doubt on shared library. i was going on line tutorial on shared library below is the code. please help me understand thank you a lot.

ctest1.c

void ctest1(int *i)
    {
       printf("I am in shared library");
       *i=100;
     }

ctest1.h

#ifndef CTEST_H
#define CTEST_H

#ifdef __cplusplus
extern "C" {
#endif

void ctest1(int *);
#ifdef __cplusplus
}
#endif

#endif

mytry.c

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include "ctest1.h"

int main(int argc, char **argv)
{
   void *lib_handle;
   double (*fn)(int *);
   int x=990;
   char *error;

   lib_handle = dlopen("libmylibrary.so", RTLD_LAZY);  // opening the shared library
   if (!lib_handle)
   {
      fprintf(stderr, "%s\n", dlerror());
      exit(1);
   }

 fn = dlsym(lib_handle, "ctest1");  //storing the address of shared library function
   if ((error = dlerror()) != NULL)
   {
      fprintf(stderr, "%s\n", error);
      exit(1);
   }


   fn(&x);
   printf("Valx=%d\n",x);

   dlclose(lib_handle);
   return 0;
}

step 1 : created a object file using -c option gcc -c my ctest1.c

step 2 :created shared library using -shared option gcc -shared -libmylibrary.so ctest1.c

step 3 : compiling my main source code ie mytry.c gcc -rdynamic -o run mytry.c -ldl

step 4: ./run

All went good with above code but i have some doubt please help me to understand.below is the list.

  1. Why function pointer ie fn return type is double although it is holding the address returned by dlsym which is void * ?

  2. if i try the same code in c++ using below command

    g++ -rdynamic -o run mytry.cc -ldl

    why do i get error as invalid conversion from void * to double( ) (int ) how can i fix it ?

    fn = dlsym(lib_handle, "ctest1"); //storing the address of shared library function this is line where i get error if i try in c++

C++ is more strongly typed than C, so pointers of type void* are not automatically converted to pointers of another type. Therefore, if dlsym returns void* , you have to explicitly cast the result in C++ when storing it in fn , which is of type double(*)(int*) .

However, your function ctest1 if not of type double(*)(int*) . It's unsafe to convert it to that. You need to change the type of fn to void(*)(int*) . Otherwise the conversion is unsafe.

The syntax to cast void* to a function pointer it is pretty ugly:

fn = (void(*)(int*))dlsym(lib_handle, "ctest1");

So it's probably better just to use typedef .

typedef void (*ctestptr)(int*);
ctestptr fn = (ctestptr)dlsym(lib_handle, "ctest1");

c code doesn't support polymorphism, therefore functions are searched only by name. but in c++ you can have a few functions with the same name, so types must be checked.

the question is what you think should happen when you return void and threat it like double?

what you really should do:

typedef void (*fnptr)(int *); //create a typedef for easy casting.
fnptr fn = (fnptr)dlsym(lib_handle, "ctest1");//cast dlsym return value.

note the signature of the function pointer is the same as the function signature.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM