Угадай тип возвращаемой функции во время выполнения - PullRequest
1 голос
/ 12 апреля 2019

Мне было интересно, могу ли я «угадать» тип возвращаемого значения функции во время выполнения.Чтобы быть более конкретным, я использую dlopen для загрузки файла динамической библиотеки, а затем, вызывая dlsym, я загружаю функцию (давайте назовем ее foo).Функция foo была написана и скомпилирована от пользователя (как общий объект) и может иногда возвращать double или int.Так, например, пользователь может определить foo как:

extern "C" {
int foo(int a){

    return a+2;
}
}

или:

extern "C" {
float foo(int a){

    return 1.0;
}
}

У меня есть скомпилированный код, который загружает файл .so (поэтому файл скомпилирован из пользователя),Фрагмент кода следующий:

typedef int (*functionPointer)  (int ); //this sometimes is typedef int 
typedef float (*functionPointer)  (int ); //or typedef float
//can i "guess" the return type at runtime?
void *handle = dlopen(userLib.so, RTLD_LAZY);
functionPointer func = (functionPointer) dlsym(handle, "foo");
func(2);

И я хочу знать, можно ли угадать этот typedef во время выполнения.Приведенный выше фрагмент уже скомпилирован и «doesent» знает, какой будет функция в данном общем объекте.

Ответы [ 2 ]

0 голосов
/ 13 апреля 2019

Мне было интересно, смогу ли я 'угадать' тип возвращаемого значения функции во время выполнения.

Нет, вы не можете. На самом деле, в некоторых ABI вам может понадобиться знать тип возвращаемого значения, чтобы вообще безопасно вызывать функцию, так как тип возвращаемого значения используется для определения того, сколько места нужно зарезервировать в стеке для возвращаемого значения.

0 голосов
/ 13 апреля 2019

То, что вы просите, невозможно в C, так как такая информация не сохраняется в скомпилированном исполняемом файле.Если у вас нет доступа к исходному коду динамической библиотеки или, по крайней мере, к соответствующим заголовочным файлам, вам придется разобрать и проанализировать его, чтобы выяснить тип возвращаемого значения.

Одна вещь, которую вы можете сделатьэто, например, составить список известных хэшей динамических библиотек, для которых вы знаете, тип возвращаемого значения - int.Затем вы можете вычислить хэш библиотеки во время ее загрузки и соответствующим образом привести указатель функции:

typedef int (*functionPointerInt)  (int ); 
typedef float (*functionPointerFloat)  (int ); 
_Bool returnTypeIsInt = so_hash_in_table("userLib.so");
void *handle = dlopen("userLib.so", RTLD_LAZY);
if(returnTypeIsInt)
{
    functionPointerInt func = (functionPointerInt) dlsym(handle, "foo");
    func(2);
}
else
{
    functionPointerFloat func = (functionPointerFloat) dlsym(handle, "foo");
    func(2);
}

Конечно, это требует предварительного анализа файлов .so.

...