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 に答える