Вызов функции из разделяемой библиотеки в GCC со встроенным ассемблером - PullRequest
1 голос
/ 22 февраля 2012

Я создал общую библиотеку (будет использоваться как плагин). Есть много функций, таких как

extern "C" long __attribute__ ((__cdecl__)) SumAgrs(long X, long Y, long Z, long *Out)
{
    *Out = X + Y + Z;
    return 0;
}

Я хотел бы вызывать функции из этой библиотеки на C ++ (GCC, Linux), но не во время компиляции. Когда я использую встроенный ассемблер, инструкция «push» повреждает локальные переменные, и я понятия не имею, как это исправить.

typedef int (*FARPROC)();

void *dl_handle = dlopen("plugin.so", RTLD_LAZY);
FARPROC proc = (FARPROC)dlsym(dl_handle, "SumAgrs");

long result;

asm("leal %0, %%eax\n\r" \
    "pushl %%eax" : : "m" (result));
asm("pushl $10");
asm("pushl $15");
asm("pushl $20");
asm("call *%0" : : "m" (proc));

Двоичный файл результата содержит что-то вроде call * 24 (% esp) . Поэтому мои pushl change % esp и call вызывают ошибку сегментации. Но как избежать такого поведения?

ТНХ

Ответы [ 2 ]

1 голос
/ 23 февраля 2012

Посмотрите на libffi: «Переносимая библиотека интерфейса с внешними функциями»

"Библиотека libffi предоставляет переносимый высокоуровневый интерфейс программирования для различных соглашений о вызовах. Это позволяет программисту вызывать любую функцию, указанную в описании интерфейса вызова, во время выполнения."

http://sourceware.org/libffi/

0 голосов
/ 22 февраля 2012

На самом деле вам не нужен ассемблер для вызова функций:

extern "C" 
{
    typedef long __attribute__ ((__cdecl__)) (*Proc)(long X, long Y, long Z, long *Out);
}

void *dl_handle = dlopen("plugin.so", RTLD_LAZY);
Proc proc = (Proc)dlsym(dl_handle, "SumAgrs");

proc(...); // call

Обратите внимание, что либо вы вызываете функции с помощью c-кода, либо с помощью встроенного ASM, ваш код для вызова генерируется за время компиляции . Вы не можете передать string переменную в asm, потому что код для вашего asm inline должен генерироваться во время компиляции программы. Это означает, что вы не можете сделать

std::string asm_code;
std:: cin >> asm_code;
asm(asm_code);
...