1

私には、他の共有ライブラリのいくつかの(古い)バージョンの代わりとして使用できる共有ライブラリを作成する仕事があります。

今問題:

私は組み合わせる必要があります:

ライブラリa:

const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl, unsigned int enum_id);
const char *mixer_ctl_get_name(struct mixer_ctl *ctl);

ライブラリb:

int mixer_ctl_get_enum_string(struct mixer_ctl *ctl, unsigned int enum_id, char *string, unsigned int size);
int mixer_ctl_get_name(struct mixer_ctl *ctl, char *name, unsigned int size);

いくつかの量のinput-paramsを処理する方法を見つけましたが、今ではそれらにも異なるreturn-typeがあります。この例はC++で見つかりましたが、Cでは見つかりませんでした。

これどうやってするの?

CがJavaのように機能する場合は、両方を実装するだけですべてが正常ですが、Cではどうでしょうか。

よろしくお願いします!

4

3 に答える 3

0

Cには関数のオーバーロードはありません。

理由は、アセンブリ生成に名前マングリングがないためです。C ++では、異なる型のオーバーロードされた関数は、Cでは異なるマングル名を持ちます-そうではありません。

したがって、一般的な方法は、次のように、異なるタイプの関数に異なる名前を指定することです。

float sqrtf(float x);
double sqrt(double x);
long double sqrtl (long double x);

等々...

于 2013-01-25T08:36:56.820 に答える
0

Cは関数のオーバーロード機能を提供せず、共有ライブラリメカニズムも提供しません。関数呼び出しを区別する唯一の方法は、異なる名前を付けることです。

さまざまなインターフェイス(リターンタイプ、パラメーターなど)の問題を解決するには、3つの共有ライブラリを構築することをお勧めします。

  1. 特定のインターフェースと機能を組み合わせた共有ライブラリ
  2. アプリケーションAのプロキシ共有ライブラリ。期待されるインターフェイスを提供し、結合されたライブラリに呼び出しを渡します。
  3. アプリケーションBのプロキシ共有ライブラリ。期待されるインターフェイスを提供し、結合されたライブラリに呼び出しを渡します。

言うまでもなく、結合されたライブラリを直接使用するには、時間の経過とともにアプリケーションAとBを変更する必要があります。

于 2013-01-25T08:36:57.217 に答える
0

簡単な解決策や一般的な解決策はありません。

C ++では、関数をクラスにパッケージ化でき、関数名はクラス内で一意である必要があります。Cにはこれがありません。

C ++では、戻り型と引数の型は関数名の一部としてカウントされます(したがってvoid foo(int)void foo(float)実際には異なる関数であり、コンパイラーはどちらを呼び出すかを認識しています)。Cにはこれがありません。

Cには、単一のグローバル名前空間があり、型は関数名の一部としてカウントされません。他の人が指摘しているように、標準のC関数名は、戻り値のタイプによって異なりsqrt()ます。returnsdoublesqrtf()returnsfloatです。

Cには、さまざまな数の引数を取ることができる関数があります。古典的な例はprintf()です。しかし、これらは書くのが難しいものであり、問​​題の一般的な解決策ではありません。「フォーマット文字列」引数がprintf()あり、printf()関数はフォーマット文字列が。への引数と正しく一致することを信頼する必要がありますprintf()。(まあ、printf()一般的であるため、一部のコンパイラは実際に引数に対してフォーマット文字列をチェックしますが、ライブラリ関数にはこの利点がありません!)

私はCで多くの作業を行いましたが、単一のグローバル名前空間はCの最も厄介な制限の1つです。このプロジェクトで実際にC ++を使用できる可能性はありますか?C ++の基本機能を使用する場合は、それを「C with classes」として扱い、名前空間と関数のオーバーロードを利用することができます。

それ以外の場合は、リファクタリングツール、またはテキストエディタの非常に優れた検索と置換機能を使用して、関数名をグローバルに一意になるように変更するのが最善の策だと思います。これを行うための明白な方法は、すべての関数を変更して、プレフィックスとしてライブラリ名を使用することです。

const char *a_mixer_ctl_get_name(struct mixer_ctl *ctl);  // library a
int b_mixer_ctl_get_name(struct mixer_ctl *ctl, char *name, unsigned int size);  // library b

次に、古いライブラリを使用してプログラムをリファクタリングまたは検索して置換する必要がありますが、ライブラリは相互に矛盾しているため、簡単に作業を再開できます。

于 2013-01-25T08:44:40.670 に答える