0

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

在此先感谢,/*乔纳斯*/

4

1 回答 1

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

希望这有帮助。

问候。

于 2012-07-29T17:39:22.447 回答