2014-11-21 81 views
-1

我對客戶有問題。他要求我設置一個帶有鍵/值的數據庫表,其中的值是C函數的名稱。 他希望我構建一個通用可執行文件,該文件將獲取該表的記錄並調用存儲到C庫中的函數。他希望能夠在不修改可執行文件的情況下插入或更新新的鍵/值對,並能夠更改所調用的函數。通過字符串指向函數的指針

舉個例子,我西港島線升貼現在很類似:

int sum(int a, int b) 
{ 
    return a+b; 
} 

int sub(int a, int b) 
{ 
    return a-b; 
} 

int (*funcion) (int,int); 


{ 
    ... 
    funcion = (void*)"sum";  
    x = funcion(4,3); 
    funcion = (void*)"sub"; 
    x = funcion(4,3);  
} 

難道這是否可行呢? 謝謝!

+3

我會說這是最樂觀的。也許如果你把這個方法和'dlsym'結合起來? – 2014-11-21 12:32:41

+2

也許最好的方法是使用[動態鏈接庫](https://en.wikipedia.org/wiki/Dynamic_loading),然後你可以按名稱查找函數(例如,在適當的操作系統上使用'dlsym',或Windows上的「GetProcAddress」)。 – 2014-11-21 12:33:56

+2

您需要在程序中將永久性函數句柄(可能是名稱或數組索引)映射到函數指針。使用動態加載器或手動。第一種是自動化更容易,第二種更安全。 – Deduplicator 2014-11-21 12:34:13

回答

0

您需要一個「查找表」。 問題是你需要定義編譯前可以調用的所有函數。爲了添加新功能,您需要更改代碼。但如果這對你有好處,這應該做的工作。

#include <stdio.h> 
#include <string.h> 

typedef enum 
{ 
    _printf, 
    _scanf, 
} functions; 

void *get_function_ptr(int func) 
{ 
    switch (func) 
    { 
     case _printf: return &printf; 
     case _scanf: return &scanf; 
     default:  return NULL; 
    } 
} 

int main(int argc, char **argv) 
{ 
    if (strcmp(argv[1], "printf") == 0) 
    { 
     void (*ptr)(char *, char *) = get_function_ptr(_printf); 
     (*ptr)("%s", "hi there"); 
    } 
} 

另一種方法是,在註釋上面說的,動態鏈接庫,但隨後你操作系統的依賴性。

+0

這裏的事情是我已經有一個庫,所有**可以被稱爲**的功能,所以我認爲使用** dlsym **將起作用。 Solaris?這是** dlsym **標準C庫嗎? – 2014-11-21 13:00:35

+0

** dlsym **不是標準C庫的一部分,而是POSIX/UNIX API的標準,它可以在Solaris下運行,但如果您知道所有功能(可能會被調用)(圖書館不會改變)你可以使用我的方法 – LMF 2014-11-21 13:06:20

+0

剛剛從一次會議回來,我的客戶優先考慮的是儘快完成代碼,因此我們將編碼所有可能的函數調用並結束的故事¬¬ 感謝你們所有的人! – 2014-11-21 13:43:19