使用内联汇编程序从GCC中的共享库调用函数

时间:2012-02-22 19:41:12

标签: c++ gcc assembly call shared

我创建了共享库(将像插件一样使用)。有许多功能,如

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 更改%esp 调用会导致细分错误。但是如何避免这种行为?

THX

2 个答案:

答案 0 :(得分:1)

查看libffi:“便携式外部函数接口库”

“libffi库为各种调用约定提供了一个可移植的高级编程接口。这允许程序员在运行时调用由调用接口描述指定的任何函数。”

http://sourceware.org/libffi/

答案 1 :(得分:0)

实际上你不需要汇编来调用函数:

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内联调用 compile 时生成的调用代码。您无法将string变量传递给asm,因为在程序编译期间应生成asm内联的代码。这意味着你无法做到

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