2016-06-21 4 views
0

ファイル記述子を使用してライブラリを作成している場合は、lib_init()から返す必要があります。上位層のコードを使用してlib_do_stuff()呼び出しに渡す必要があります。そして、いつ私はCライブラリのprivate "member"として静的な.cファイルとして残すことができますか?C.のファイル記述子は、静的なグローバルと対戦します。

私のライブラリのユーザがファイルディスクリプタに制御またはアクセスする必要がないと思うなら、C++のようにファイルディスクリプタをそのまま残すことができますか?privateですか?

いずれにしてもそれを行うための短所は何ですか?

+1

一般的なアドバイスとして、決して静的なグローバル変数を使うべきではありません。代わりに、必要なすべての変数をメンバーとして含む「ブラックボックス」構造を作成し、初期化関数からのポインタを返すことをお勧めします。 C標準のI/O関数とよく似ています。 'fopen'は未定義の' FILE'構造体へのポインタを返します。 –

+0

どのようにして、必要なすべての内部変数をC言語のメンバーとして定義できますか?私には翻訳単位全体が利用可能であるが、翻訳されることはできないということです。それはかなり静的なグローバル変数ですよね? – justynnuff

+0

これは「ブラックボックス」構造に関する素晴らしいことです。あなたのAPIのユーザーが気付かれることなく、必要に応じて新しいメンバーを追加したり、古いものを削除したり、既存のものを変更したりすることができます。 –

答えて

3

例を使用して私の提案を拡大してください。

あなたのライブラリには、少なくとも2つの(少なくとも)ヘッダファイルが必要です。ライブラリのユーザには1つの公開があり、ライブラリのソースファイルには1つしか含まれません。

国民が

#pragma once 

// This is all that is needed to declare pointers to the internal structure 
typedef struct internal_structure STRUCTURE; 

// The public API of your library 
STRUCTURE *lib_init(void); 
void lib_cleanup(STRUCTURE *s); 
... 

のようなものかもしれないそうすれば、プライベートヘッダファイルに

#pragma once 

struct internal_structure 
{ 
    int fd; 
    // Other members as needed 
    ... 
}; 

// Possible function prototypes of private functions 

を持っその後、あなたのライブラリーのソースファイルに、あなたは、パブリックおよびプライベートヘッダファイル、および使用の両方が含まれますブラックボックス構造のSTRUCTURE

#include <stdlib.h> 
#include "public.h" 
#include "private.h" 

STRUCTURE *lib_init(void) 
{ 
    STRUCTURE *s = malloc(sizeof *s); 
    s->fd = open(...); 
    // Other initialization 
    ... 
    return s; 
} 

void lib_cleanup(STRUCTURE *s) 
{ 
    // Other cleanup 
    ... 
    close(s->fd); 
    free(s); 
} 

は、その後、あなたのライブラリーのユーザーのみ公共のヘッダファイルが含まれており、あなたの明確に定義されたAPIを使用しています。

#include "public.h" 

int main(void) 
{ 
    STRUCTURE *s = lib_init(); 
    ... 
    lib_cleanup(s); 
    return 0; 
} 

公共の機能は、すべてのと同様に、その引数の一つ、典型的には、その最初の引数としてSTRUCTURE *を取る必要がありますlib_cleanup機能。この関数は、構造体とそのメンバを任意の方法で使用できます。

+0

さて、各ソースライブラリファイルのヘッダーファイルが2倍になったので、誰でも使用できるヘッダーファイルに "//可能な関数プロトタイプのプライベート関数"を入れることをお勧めします。ポイント。ユーザーは自分の内部変数にアクセスできます。 多分私は間違った考え方をしているので、あまりにも多くのWebアプリケーションで作業していましたが、私が「私的メンバー」を持っていることを暗示しているときは、複雑なコードを書くだけではありません。あいまいさによるセキュリティ。 – justynnuff

+0

@justynnuffはい、以前と同じようにヘッダーファイルが2つありますが、ソースファイルごとに1つではなく、合計で*** ***ヘッダーファイルが2つしかありません。それとも、すべてのライブラリのソースファイルに2つのヘッダファイルをインクルードする必要がありますか?そう、はい、そうです。しかし、それはあなたが考えることができる唯一の欠点である場合は特に、IMOを支払うための小さな価格です。 –

+0

@justynnuffまた、プライベートヘッダーファイルをインストールしないでください。***プライベート***。そして、これは非常に一般的なパターンです。それは「あいまいさを通したセキュリティ」ではありません。少なくとも、あなたが開いている場合はそうではありません。コード自体は、構造全体を公開した場合よりも複雑ではありません。これも非常に一般的です。そして、ライブラリコードを再入可能にするための最良の方法の1つです。複数のスレッドにそれぞれライブラリ用の別個の「ハンドル」を持たせることができます。 –

関連する問題