2012-02-22 35 views
1

我創建了共享庫(將用作插件)。還有像一個使用內聯彙編器從GCC的共享庫調用函數

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)); 

結果二進制文件包含有類似呼叫* 24(%ESP)。所以我的pushl更改%尤其調用導致分段錯誤。但是如何避免這種行爲?

THX

回答

1

看libffi:「一個便攜式外部函數接口庫」

「的libffi庫提供了一個可移植的,高層次的編程接口,以各種調用約定這允許程序員在運行時調用由調用接口描述指定的任何函數。「

http://sourceware.org/libffi/

1

你不必彙編程序調用的功能,實際上是:

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。這意味着你不能做

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

將從腳本調用函數並將參數存儲在數組中。所以編譯時間「調用」不是解決方案。 – zdenek 2012-02-22 20:04:41

+0

@ user1173308,請參閱我的編輯 – Lol4t0 2012-02-22 20:10:57

+0

不,不,用ASM內聯,代碼將在運行時生成。例如(僞代碼):** foreach(params){push parm; } call func; ** – zdenek 2012-02-22 20:26:04