0

3 つの *.h ファイルがあります。

あ:

<some types>
extern sometype1 somevar1;

Bh:

<some types>
extern sometype2 somevar2;

チャンネル:

<some types>
extern sometype3 somevar3;

そして、私はDcファイルを持っています:

#include "A.h"
#include "B.h"
#include "C.h"

int freethemall()
{
    TheFunctionFromAhFileForFreeingTheSomevar1Resources();
    TheFunctionFromBhFileForFreeingTheSomevar2Resources();
    TheFunctionFromChFileForFreeingTheSomevar3Resources();
}

このプロジェクトはある種のフレームワークです。

場合によっては、すべてのモジュール (A、B、または C) が必要ないことがあります。たとえば、A と B モジュールのみが必要な場合があります。しかし、フレームワークの初期化の構造は次のとおりです。

#include "A.h"
#include "B.h"
<Frameworkname>Init();

<do some code here>

<Frameworkname>Free();

そのため、ただ 1 つの ...Free() 関数ではなく、すべてのモジュールからすべての Free 関数を呼び出すのは非常に不快です。

#include "A.h"
#include "B.h"
<Frameworkname>Init();

<do some code here>

<Frameworkname><modulename1>Free();
<Frameworkname><modulename2>Free();
..
<Frameworkname><modulenameN>Free();

この場合、N は 2 しかありませんが、約 20 個のモジュールがあるため、それらをすべて数えるのはプログラマーに優しくありません。

freethemall() 関数を変更して、使用およびインクルードしたモジュールのデストラクタのみを呼び出すにはどうすればよいですか? Dhにはその機能が含まれており、Dhを含むモジュールがたくさんあることに注意してください

PS 必要に応じて、他のすべてのモジュールに Dh モジュールを含めることができます。

それを解決する別の方法として、最後の Delphi 言語のように、モジュールのファイナライズの前に呼び出される関数が必要です。

Unit ...

Finalization
   Callme;
End.

freethemall() から呼び出す必要はありませんが、この問題を解決するための何らかのリードです。

アドバイスありがとうございます。

4

5 に答える 5

1

2 つの方法:

  1. 「ハック」は、各モジュールで #define を実行することです。または、モジュールのコードにアクセスできない場合は、#define USE_A および ifdef USE_A を実行して、実際にヘッダーをインクルードします。したがって、#define を変更すると、ヘッダーが含まれるかどうかが決まり、解放のための関数が同じ定義をチェックします。

  2. 正しい方法は、解放する必要があるアイテムを「登録」する機能を持つことです。ポインターの配列。そのため、それぞれを作成するときに、そのポインターまたはポインターを配列に解放する関数へのポインターを追加します。解放する必要がある場合は、配列をループして、それぞれを解放します。

于 2013-11-11T16:58:37.030 に答える
0

あなたの問題を解決するためにヘッダーガード* 1 (とにかく欠けている)を使うことができます:

次のようにヘッダーを変更して、ヘッダー ガードを追加します。

あ:

#ifndef _A_H
#define _A_H

<some types>
extern sometype1 somevar1;

#endif

Bh:

#ifndef _B_H
#define _B_H

<some types>
extern sometype2 somevar2;

#endif

チャンネル:

#ifndef _C_H
#define _C_H

<some types>
extern sometype3 somevar3;

#endif

そして、私はDcファイルを持っています:

#include "A.h"   /* \                                            */
#include "B.h"   /*  \                                           */
#include "C.h"   /*   + <--- comment in/out here what is needed. */
...              /*  /                                           */
#include "_n_.h" /* /                                            */


int freethemall()
{
    #ifdef _A_H
    TheFunctionFromAhFileForFreeingTheSomevar1Resources();
    #endif

    #ifdef _B_H
    TheFunctionFromBhFileForFreeingTheSomevar2Resources();
    #endif

    #ifdef _C_H
    TheFunctionFromChFileForFreeingTheSomevar3Resources();
    #endif

    ...

    #ifdef __n__H
    TheFunctionFromChFileForFreeingTheSomevar_n_Resources();
    #endif

    return 0;
}

ヘッダー ガードの定義の#include行をコメント イン/アウトすることで、さまざまなフィールドのコードのどの行を非アクティブ化/アクティブ化するかを操作するために使用されます。 D.c*.hfreethemall()


*1 ヘッダー ガードについては、ここをクリックして回答を下にスクロールしてください

于 2013-11-11T18:50:32.927 に答える
0

プログラムの起動時にユーザーが呼び出す必要がある初期化関数を作成できます。その関数は、ユーザーが使用するモジュールに渡されます。ライブラリはその情報を保存し、シャットダウン時に適切な関数を呼び出します。

例:

/* Header file */

enum SmlModule {
    SML_RASTER = 1,
    SML_EVENT  = 2,
    SML_TIME   = 4
}

int sml_init(int modules);

次に、プログラムで:

int main ()
{
    sml_init(SML_RASTER | SML_TIME);
    (...)
    return 0;
}

このアプローチは、SDLライブラリなどで使用されます。SDL_Initを参照してください。

于 2013-11-11T17:11:01.570 に答える
0

これが彼らが c++ を作成した理由です。過負荷メカニズムは、ここでの問題を簡単に解決します。しかし、あなたはCでそれをしなければならないので、私が知っている唯一の方法はビットフィールドを使うことです.

Free(uint32 bitfield){

int i,masklen =32;

for (i=0;i<masklen;i++)
{
  if (bitfield & 1<<i)
    // call free for module i
    // you can have an array of function pointers so that you easily get the right
    // free function each time 
} 
}

これにより、ビットフィールドに別のタイプが必要な場合は32個のモジュールが可能になります

于 2013-11-11T16:56:50.333 に答える
-1

あなたが望んでいることは不可能だと思います。

C++ では、オブジェクトの宣言 (ヘッダーまたはモジュール内のいずれか) によってコードが実行される可能性があるため可能ですが、C では実行できません。

こうすれば

main.h:

typedef struct {
    void (*init)(void) ;
    void (*exit)(void) ;
    } MODULE ;

A.h:
extern MODULE A ;

B.h
extern MODULE B ;

main.c:

#include    "main.h"
#include    "A.h"
#include    "B.h"

MODULE modules[] = {
&A,
&B,
0,
} ;

次に、init,exit フェーズで modules 配列を反復処理し、それらのフェーズに適切な関数を呼び出します。

そうすれば、2行を維持するだけで済みます。これは、私が考えることができる最もコンパクトで保守可能な方法です。

于 2013-11-11T17:02:53.950 に答える