简体   繁体   English

是否可以创建一个泛型函数指针数组?

[英]Is it possible to create an array of generic function pointers?

I'm writing an interface layer to a shared library we are opening via dlopen/dlsym.我正在为我们通过 dlopen/dlsym 打开的共享库编写一个接口层。 The parameters to the functions may change depending on whether the library is compiled for system A vs system B.根据库是为系统 A 还是系统 B 编译库,函数的参数可能会发生变化。

I had a thought that instead of doing a bunch of typedefs, I could try to create an array of all of the function pointers returned from dlsym and then eventually use VA_ARGS to pass in the data.我有一个想法,与其做一堆 typedef,我可以尝试创建一个包含从 dlsym 返回的所有函数指针的数组,然后最终使用 VA_ARGS 来传递数据。 This would also allow me to deal with extensibility-- if the library parameters change, we'd just need to update the calling functions, instead of the typedefs below, too.这也可以让我处理可扩展性——如果库参数发生变化,我们只需要更新调用函数,而不是下面的 typedef。 Basically, I'm looking to change something like this:基本上,我希望改变这样的事情:

typedef int* (*foo_t)(int, int);
typedef int* (*bar_t)(int, int, char*, int);
typedef void (*baz_t)(void);

void GetStuff()
{
  void *handle = dlopen("/my/cool/libLibrary.so", RTLD_LAZY);
  foo_t foo = dlsym(handle, "TheFooFunction");
  bar_t bar = dlsym(handle, "TheBarFunction");
  baz_t baz = dlsym(handle, "TheBazFunction");

  foo(1, 2);
  bar(3, 4, "cool", 5);
  baz();
}

into this:进入这个:

enum funcs
{
  FUNC_FOO = 0,
  FUNC_BAR = 1,
  FUNC_BAZ = 2,
  FUNC_MAX
};

void funcArray[FUNC_MAX]; // Not legal - looking for a way to do something like this...

char *functionNames[FUNC_MAX] =
{
   [FUNC_FOO] = "TheFooFunction",
   [FUNC_BAR] = "TheBarFunction",
   [FUNC_BAZ] = "TheBazFunction"
};

void GetStuff()
{
  void *handle = dlopen("/my/cool/libLibrary.so", RTLD_LAZY);
  for (int i = 0; i < FUNC_MAX; i++)
  {
    funcArray[i] = dlsym(handle, functionNames[i]);
  }

  funcArray[FUNC_FOO](1, 2);
  funcArray[FUNC_BAR](3, 4, "cool", 5);
  funcArray[FUNC_BAZ]();
}

Is this possible?这可能吗? I know the array of voids is illegal.我知道空数组是非法的。 I can't use uintptr_t in it's place, since those are for data (not function) pointers.我不能在它的位置使用 uintptr_t,因为它们用于数据(不是函数)指针。 Are there any other options other than creating big #define's for each configuration and doing it the original way?除了为每个配置创建大 #define 并以原始方式进行操作之外,还有其他选择吗?

Declare the array as an array of function pointers.将数组声明为函数指针数组。 Actually the type of function pointer does not matter.实际上函数指针的类型并不重要。

void (*funcArray[FUNC_MAX])();

Then right before you call you have to convert your function pointers to the correct type:然后就在您调用之前,您必须将函数指针转换为正确的类型:

((int *(*)(int, int))funcArray[FUNC_FOO])(1, 2);
((int *(*)(int, int, char*, int))funcArray[FUNC_BAR])(3, 4, "cool", 5);
((void (*)(void))funcArray[FUNC_BAZ])();

There are two main ways to achieve run-time selection of the type signature of a function being called.有两种主要方法可以实现对被调用函数的类型签名的运行时选择。

  1. Have a switch statement somewhere which switches on an integer code (designed by you) indicating the function type.在某处有一个switch语句,它打开指示函数类型的整数代码(由您设计)。 The switch cases are all calls which cast the function pointer differentlly and call it with different arguments. switch case 是所有调用,它们以不同的方式转换函数指针并使用不同的参数调用它。

  2. Use a library for constructing funcction calls dynamically, such as libffi (MIT-like license) or libffcall , (GPL-licensed GNU software).使用库来动态构造函数调用,例如libffi (类似 MIT 的许可证)或libffcall ,(GPL 许可的 GNU 软件)。

Option 2 requires more demanding coding and may be overly general for a situation like this.选项 2 需要更苛刻的编码,对于这种情况可能过于笼统。 The purpose of these libraries is to support dynamic languages being able to call C libraries.这些库的目的是支持能够调用 C 库的动态语言。 A dynamic language can use libffi or libffcall as a back end for translating the description of a function into an object which can be used to call it.动态语言可以使用 libffi 或 libffcall 作为后端,将函数的描述转换为可用于调用它的对象。

Option 2 hints at an option 3: Write your program, or a portion of it, in a higher level language that has good FFI, and leverage that to achieve the flexible calls into the shared libraries.选项 2 暗示了选项 3:使用具有良好 FFI 的高级语言编写您的程序或其中的一部分,并利用它来实现对共享库的灵活调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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