2012-07-29 41 views
0

我在錯誤代碼的最佳設計和C項目中的相應錯誤消息上沉思。該項目由一個提供核心功能的小內核組成,可以通過各種插件進行擴展。內核已經定義了最一般的錯誤代碼,例如PROJ_NOERR(無錯誤)或PROJ_ENOMEM(無內存可用)。此外,插件還應能夠定義特殊的錯誤代碼及其相應的消息,例如,一個Web服務器插件可以定義WEBSERV_ESOCKET(套接字錯誤)。在我看來,內核還應該提供將錯誤代碼轉換爲相應錯誤消息的功能,例如, extern char * proj_err2str(enum err_t);該函數還應該能夠處理所有加載插件的定義的錯誤代碼。你將如何實施這樣一個系統?歡迎任何提示!插件系統中的錯誤代碼和消息處理

在此先感謝, /* *喬納斯/

回答

1

我真的不明白你的意思,但在這裏你如何創建你的插件示例代碼:

/* This struct is common to all plugins and the functions defined here must be implemented by all plugins*/ 
typedef struct 
{ 
    int (*plugin_function_one) (char *str); 
    void (*plugin_function_two) (int fd); 
    void (*plugin_handle_error) (char *err, int status); 
    char plugin_errors_codes[ERR_CODES_NUM]; // Each plugin can add errors code here 
} plugin_t; 

你可以然後創建一個插件(plugin_one)例如像這樣:

int plugin_function_one(char *str) 
{ 
    // Body of function_one 
} 

void plugin_function_two(int fd) 
{ 
    Body of function_two 
} 

// Here you have your error handling function for plugin_one 

void plugin_handle_error(char *err, int status) 
{ 
    fprintf(stderr,"Plugin --> Got this error: %s and errno = %d", strerror(err), errno); 
    // depend on status, we can exist or not for exampe 
    if (status) 
     exit(EXIT_FAILURE); 
} 

現在初始化你的插件:

plugin_t * plugin_init (plugin_t * p) 
{ 
    /* Plugin init */ 
    p-> plugin_function_one = plugin_function_one; 
    p-> plugin_function_two = plugin_function_two; 
    p-> plugin_handle_error = plugin_handle_error; 

    /* init the array of errors here */ 
    init_plugin_errors(p->plugin_errors_codes); 
    /* return the newly created plugin */ 
    return (p); 
} 

您可以加載並上傳所有的插件,像這樣:

int plugin_load (char *path_to_your_plugin) 
{ 
    void *dh; 
    plugin_t *(*p_init) (plugin_t * p); 
    plugin_t dp; 

    /* opening plugin */ 
    dh = dlopen (path_to_your_plugin, RTLD_LAZY); 
    if (NULL == dh) 
    { 
     fprintf (stderr, "Failed to load '%s' (errno=%d, msg='%s')\n",path_to_your_plugin, errno, strerror (errno)); 
      exit (EXIT_FAILURE); 
     } 

    /* Now we look for plugin_init function */ 
    p_init = dlsym (dh, "plugin_init"); 
    if (NULL == p_init) 
     { 
      fprintf (stderr, "Failed to get 'plugin_init'\n"); 
      dlclose (dh); 
      exit (EXIT_FAILURE); 
     } 

    /* We init the plugin */ 
    if (NULL == p_init (&dp)) 
     { 
      fprintf (stderr, "Error plugin_init()\n"); 
      dlclose (dh); 
      exit (EXIT_FAILURE); 
     } 

    ….. 

    /* Calling plugin functions */ 
    dp.plugin_handle_error(char *err, int status); 
} 

和卸載插件:

int plugin_unload (char * path_to_your_plugin) 
{ 
    /* Need the address of the loaded plugin to call dlclose, let's call it the_address */ 
    if (the_adress != NULL) 
     fprintf(stdout, "This plugin will be unloaded : %p", the_adress); 
    /* close plugin. */ 
    dlclose (the_adress); 

    return 0; 
} 

要處理不同的插件中重複的錯誤代碼,功能err2str需要知道哪個插件正在提交請求:

int err2str (plugin_t *plugin, int error_code) 
{ 
    // Lookup in the plugin_errors_codes array 
    char *my_error; 
    my_error = error_lookup(plugin->plugin_errors_codes, error_code); 
    print_error(my_error); 
} 

Hope thi幫助。

問候。

+0

感謝您的詳細解答。我的問題不是關於插件管理器,而是針對錯誤處理功能。我希望插件可以定義自己的錯誤代碼,這些代碼在整個應用程序(內核和插件)中是唯一的。此外,我想在內核中的單個函數(err2str)可以處理所有定義的錯誤代碼,也是由插件定義的錯誤代碼。 此致敬禮! – Jonas 2012-07-29 17:50:58

+0

@Jonas:對於錯誤代碼,你可以創建一個數組來保存struct插件中的所有錯誤代碼,每個插件可以用他的錯誤代碼來初始化這個數組。我將編輯我的答案以達到此目的。 – TOC 2012-07-29 18:06:34

+0

嗯,但在這種情況下,由兩個不同插件定義的兩個錯誤代碼可以具有相同的錯誤代碼值(int)。或者我理解錯了什麼?我認爲每個錯誤代碼在所有插件中都應該是唯一的。 – Jonas 2012-07-29 18:19:57