1

コマンド ラインから実行する C で記述された科学シミュレーション コードがあります。model.cユーザーは、実行時にコードにコンパイルされる一連の C サブルーチンとして入力モデルをファイルに提供します。

一部のモデル プロパティは、特定の問題に必ずしも関連するとは限りませんが、現在、ユーザーはコードをコンパイルするために、そのプロパティに空のダミー関数を提供する必要があります。

model.cユーザー提供のプロパティにサブルーチンが含まれていない場合にのみリンクされる、ソース コードに埋め込まれたモデル プロパティのダミー サブルーチンを持つことは可能ですか?

例として、 にmodel.cと呼ばれるサブルーチンが含まれている場合temperature()、コードは にある と呼ばれるサブルーチンではなく、そのサブルーチンにリンクする必要がありtemperature()ますsrc/dummy_function.cmodel.cにない場合temperature()、コンパイラは でダミー関数を使用する必要がありますsrc/dummy_function.c

可能であれば、ファイルにプリプロセッサ ディレクティブを必要としないソリューションを希望しmodel.cます。

4

2 に答える 2

4

はい、できます。undesym.c などの単純なコードがファイルに含まれているとします。

int
main(void)
{
  user_routine();
  return 0;
}

ファイル fakeone.c に弱いスタブを作成します。

#include "assert.h"

int  __attribute__((weak))
user_routine(void)
{
  assert(0 == "stub user_routine is not for call");
  return 0;
}

次に、「ユーザー」関数を作成します。たとえば、goodone.c とします。

#include "stdio.h"

int
user_routine(void)
{
  printf("user_routine Ok\n");
  return 0;
}

一緒にリンクするとgcc undesym.c fakeone.c、 a.out が実行されてアサートされますがgoodone.c、 のようにコンパイルに追加するとgcc undesym.c fakeone.c goodone.c、弱い定義よりも強い定義が優先され、メッセージが実行されます。

同じメカニズムを採用して、デフォルト関数を weak に定義することもできます。

于 2013-03-13T15:11:54.337 に答える
0

ユーザーのサブルーチンは「実行時にコードにコンパイルされる」と言うので、動的リンクを使用してユーザー提供のバイナリをロードし、実行時にエントリポイントを探すことができます。dlopen()Linux (または任意の POSIX システム) では、これは/に基づいておりdlsym()、多かれ少なかれ次のようになります。

#include <dlfcn.h>

/* ... */

/* Link the UserModule.so into the executable */
void *user_module = dlopen("UserModule.so", RTLD_NOW);

if (!user_module) {
    /* Module could not be loaded, handle error */
}

/* Locate the "temperature" function */
void *temperature_ptr = dlsym(user_module, "temperature"):

if (!temperature_ptr) {
    /* Module does not define the "temperature" function */
}

void (*user_temperature)() = (void(*)())temperature_ptr;

/* Call the user function */
user_temperature();

詳細については、dlopen のドキュメントを参照してください。同様の機能は、使用している OS で利用できる可能性が非常に高いです。

于 2013-03-13T15:04:48.930 に答える