在c中使用共享库是好的,但在c++中使用相同的代码是不好的

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

本文关键字:c++ 代码 共享 但在      更新时间:2023-10-16

你好,我对共享库有一些疑问。我正在上网上的教程,下面是关于共享库的代码。请帮助我理解,谢谢你。

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, "%sn", dlerror());
      exit(1);
   }
 fn = dlsym(lib_handle, "ctest1");  //storing the address of shared library function
   if ((error = dlerror()) != NULL)
   {
      fprintf(stderr, "%sn", error);
      exit(1);
   }

   fn(&x);
   printf("Valx=%dn",x);
   dlclose(lib_handle);
   return 0;
}

步骤1:使用-c选项创建一个object文件

步骤2:使用-shared选项创建共享库gcc -shared -libmylibrary。所以ctest1.c

步骤3:编译我的主源代码,即mytry.cgcc -rdynamic -o run mytry.c

步骤4:。/运行

以上代码都很好,但我有一些疑问,请帮助我理解。以下是列表。

  1. 为什么函数指针即fn返回类型是double,尽管它保存dlsym返回的地址是void * ?

  2. 如果我在c++中使用下面的命令

    尝试相同的代码

    g++ -rdynamic -o运行mytry。cc ldl

    为什么我得到错误作为无效转换从void *到double() (int)我怎么能修复它?

    fn = dlsym(lib_handle, "ctest1");//存储共享库函数的地址这是我得到错误的行,如果我在c++中尝试

c++比C语言更强类型,因此void*类型的指针不会自动转换为其他类型的指针。因此,如果dlsym返回void*,当将其存储在fn (double(*)(int*)类型)中时,必须在c++中显式转换结果。

但是,如果不是类型为double(*)(int*),则函数ctest1。转换成那样是不安全的。需要将fn的类型修改为void(*)(int*)。否则转换是不安全的。

void*转换为函数指针的语法非常难看:

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

所以最好还是用typedef

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

c代码不支持多态性,因此只能按名称搜索函数。但是在c++中,你可以有几个同名的函数,所以必须检查类型。

问题是当你返回void并像double一样威胁它时,你认为应该发生什么?

你真正应该做的:

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

注意函数指针的签名和函数的签名是一样的