2016-06-18 32 views
-1

你好我的工作是工作原理是這樣的程序:dlopen不同的圖書館? ç

./Filters File [filters...]

過濾器可以有很多,我想創建自己和他們APLY到文件的.so庫。但是所有庫都具有相同的功能process(a1,a2,a3),只是它們每個都做了不同的事情。

我試圖用這樣的:

/*Open the library*/ 
if (!(descriptor_lib=dlopen(dir_filter, RTLD_LAZY))) { 
    fprintf(stderr, MYNAME": %s\n", dlerror()); 
    return(1); 
} 

/*We find the function we want to use*/ 
if (!(fn=dlsym(descriptor_bib, "process"))) { 
    fprintf(stderr, MYNAME": %s\n", dlerror()); 
    return(1); 
} 

/*And then I try to use the function*/ 
printf("Number of chars readed: %d", fn(a1, a2, a3)); 

但是,當我嘗試編譯我得到這個錯誤:error: too many arguments to function ‘fn’

dir_filter是圖書館的方向,但它的一個變量,因爲我做了一個循環來讀取所有的過濾器,在dir_filter中複製實際的過濾器,然後使用上面的代碼。

我認爲如果我指定dir_filter與庫的名稱,它會工作,但我不能這樣做,因爲我需要使它適用於不同的過濾器(不同的庫),它不會總是一樣。現在我只有3個庫,但如果將來我要擴展它,我不想每次添加新庫時都要擴展代碼。

那麼我做錯了什麼,或者它是不可能的與dlopen變量一起工作?

編輯:該功能的過程是這樣的:

int process(char*buff_in, char*buff_out, int tam) 

EDIT2:隨着typedef我可以解決的函數指針,這就是問題所在。感謝您的回覆,並對我的英語感到抱歉。

+4

顯示'fn'及其所有相關類型的聲明。所以**編輯你的問題來改善它**。您可能想要使用'typedef'來簽名,請參閱[this](http://stackoverflow.com/a/9143434/841108) –

+1

問題不在於過程函數的類型,而在於函數的類型在更新後仍然不顯示的指針。 –

+0

編譯器如何知道傳遞給'fn'的類型? –

回答

1

假設你process函數聲明(在你的插件代碼)作爲

int process(int, int, int); 

然後,你會更好define一個typedef其簽名(主程序中做dlsym):

typedef int process_sig_t (int, int, int); 

你會用它來聲明函數指針(有一些「直接」的方法來聲明函數pointer而不使用typedef爲其簽名,但我覺得他們不太可讀)。

process_sig_t *fnptr = NULL; 

編譯器會知道該指針引用的函數的簽名。

(的fnptrNULL初始化可被省略,它使得代碼更易讀且不易出錯,因爲具有更可再現的行爲)

你將填補使用dlsym例如

if (!(fnptr=dlsym(descriptor_bib, "process"))) { 
    fprintf(stderr, MYNAME": %s\n", dlerror()); 
    return(1); 
} 

使用它

printf("Number of chars read: %d\n", (*fnptr) (a1, a2, a3)); 

BTW,函數指針可以直接調用:

// less readable code, we don't know that fnptr is a function pointer 
printf("Number of chars read: %d\n", fnptr (a1, a2, a3)); 

(最好是結束最printf格式字符串與\n;否則調用fflush(3)因爲stdout通常是線路緩衝的)

順便說一句,你的問題主要是關於理解函數指針(如果函數指針是通過dlsym以外的其他值獲得的,例如,使用一些JIT compiling庫,如GCCJIT)。

+0

嘿,非常感謝你的具體。我可以解決這個問題。順便說一下,我在主帖子中更新了函數'process'的格式。 – DavidCG

+0

如果合適,您可以接受或提出我的答案。 –