実行時の動的リンクがこれを処理できるかどうかは 100% わかりません。ヘルパー関数を各実行可能ファイルに静的にリンクすると、確実に機能します。
両方のプログラムで同じ API を使用してロギング機能を提供します。何かをログに記録したいライブラリ関数にこの関数を呼び出してもらいます。ライブラリを使用しているプログラムによって提供される実装を取得します。
各プログラム、ライブラリごとにインクルードされるヘッダファイル
// common_log.h
#ifdef __cplusplus
extern "C" // for the following definition only, no opening {
#endif
// used by code that can be part of either program
void common_log(char *msg, int log_prio);
tty C++ プログラムでの実装 (単純なロギング):
#include "common_log.h"
#include <iostream>
// used by the rest of the C++ program
void simple_logger(char *msg) {
cerr << msg;
}
extern "C" void common_log(char *msg, int log_prio) {
simple_logger(msg);
}
デーモン C プログラムでの実装:
#include "common_log.h"
#include <stdio.h>
#include <errno.h>
static FILE *logfp;
static int log_level;
// used by daemon code
void fancy_logger(char *msg, int log_prio) {
if (log_prio < log_level)
return;
if (EOF == fputs(logfp, msg)) {
perror("failed to write log message to log file: ");
}
}
// or use linker tricks to make common_log an alias for fancy_log,
// if they both have the same signature and you don't need to do anything in the wrapper.
//extern "C" // this is already C
void common_log(char *msg, int log_prio) {
fancy_logger(msg, log_prio);
}
これには、リンカーが、リンクされているプログラムのシンボルを使用して、ライブラリ内の未定義のシンボルを解決できる必要があります。ライブラリがグローバル変数の弱い定義を提供するのと同様に機能すると思うので、メインプログラムの定義が優先されます。
simple_logger
が同じ署名を持っていても問題ない場合extern "C"
は、それらに同じ名前を付けて、バウンス機能を回避できます。または、共通関数がいずれかのプログラムのプログラム独自のログ関数のエイリアスである可能性がある場合、単一の命令にコンパイルするのではなく、実際にそれを行うリンカーのトリックがあると思いますjmp
(末尾呼び出しの最適化)。