C 插件系统中的错误代码和消息处理

C 插件系统中的错误代码和消息处理,c,plugins,error-code,C,Plugins,Error Code,我正在思考C项目中错误代码和相应错误消息的最佳设计。这个项目由一个提供核心功能的小内核组成,可以通过各种插件进行扩展。内核已经定义了最常见的错误代码,例如PROJ_NOERR(无错误)或PROJ_ENOMEM(无可用内存)。此外,插件还应该能够定义特殊的错误代码及其相应的消息,例如,web服务器插件可以定义WEBSERV_ESOCKET(套接字错误)。在我看来,内核还应该提供一个将错误代码转换为相应错误消息的函数,例如extern char*proj_err2str(enum err_t);此函

我正在思考C项目中错误代码和相应错误消息的最佳设计。这个项目由一个提供核心功能的小内核组成,可以通过各种插件进行扩展。内核已经定义了最常见的错误代码,例如PROJ_NOERR(无错误)或PROJ_ENOMEM(无可用内存)。此外,插件还应该能够定义特殊的错误代码及其相应的消息,例如,web服务器插件可以定义WEBSERV_ESOCKET(套接字错误)。在我看来,内核还应该提供一个将错误代码转换为相应错误消息的函数,例如extern char*proj_err2str(enum err_t);此函数还应该能够处理所有加载插件的已定义错误代码。您将如何实施这样一个系统?欢迎任何提示

提前感谢,,
/*Jonas*/

我不太明白你的意思,但这里有一个关于如何创建插件的示例代码:

/* 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);
}
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);
}
现在初始化你的插件:

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_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);
}
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); 
}
希望这有帮助


问候。

谢谢您的详细回答。我的问题不是关于插件管理器,而是针对错误处理功能。我希望插件可以定义自己的错误代码,这些代码在整个应用程序(内核和插件)中是唯一的。此外,我希望内核中有一个函数(err2str),可以处理所有定义的错误代码,也可以处理插件定义的错误代码。致以最良好的祝愿@乔纳斯:对于错误代码,你可以创建一个数组来保存struct插件中的所有错误代码,每个插件都可以用自己的错误代码初始化这个数组。我将编辑我的答案以满足这个.Hmmm,但是在这种情况下,由两个不同插件定义的两个错误代码可以具有相同的错误代码值(int)。还是我理解错了什么?我认为每个错误代码在所有插件中都应该是唯一的。但也许我的想法/想象是毫无意义的。。。我现在不确定…@Jonas:这取决于你,你可以在所有插件中生成所有错误代码uniq。这很清楚,或者每个插件都可以添加错误代码,在这种情况下,函数err2str需要知道调用哪个插件,它可以引用我展示给你的结构中的代码数组。我将编辑答案以添加此内容。