2016-05-09 27 views
2

sprintfはプラットフォームによって提供されるAPIです。私はそれが使用されるときいくつかの形式をフィルタリングしたい。私の考えは:sprintfが呼び出されるたびにmy_functionを呼び出す方法は?

​​

これらのコードをpchに入れてください。

しかし、私はまだそれがすべての用途をカバーすることができないと心配しています。あるものは事前ビルドされたライブラリにあり、すべてのプロジェクトがpchを持っているわけではありません。あなたは他の考えを持っていますか?

ありがとうございました。それは窓の上にある。あなたがいるない標準ライブラリの関数と同じ名前の関数/マクロを定義することができ:

int my_sprintf(char *buffer, char *fmt, ...) 
{ 
    int ret; 
    va_list args; 
    va_start(args, fmt); 
    /* insert your filter here */ 
    /* you CAN NOT re-use a va_list variable after being used */ 
    ret = vsprintf(buffer, fmt, args); 
    va_end(args); 
    return ret; 
} 

注:

+0

を呼び出すよりも、同じ名前

#include <stdio.h> namespace myns { int sprintf(...) { my_filter_function(...); return ::vsprintf(...); } } 

で関数を定義するために名前空間に概念を使用することができますそれを行うには、それでもあなたはすべてのケースをカバーすることはありませんが、代わりにワームの缶を開きます。だから問題は、これで実際に何を達成したいのですか?何を正確にフィルタリングしたいのですが、なぜですか?おそらく、あなたが望むものを達成するためのより良い方法があります。 – CherryDT

+0

理論的には、プラットフォームのバージョンを動的にロードし、すべての呼び出しを転送するためにGetProcAddressを呼び出すCRT dllの独自のバージョンを記述することができます。その後、上記のようにカスタムsprintfを変更するだけです。その後、マイクロソフトではなくカスタムCRTにプログラムをリンクします。そして、プログラムがすべての種類の予期せぬものを実行し、おそらくクラッシュして、なぜあなたが悩んでいるのか疑問に思うままに戻って座って見てください。 –

+0

stdoutをカスタム出力にリダイレクトFILE –

答えて

1

組み込み関数を上書きすることはできません。さらに、マクロを使用して名前を置き換えると、プログラムで未定義の動作が発生します。

標準ライブラリの動作を変更しないでください。本当に、その方法狂気が嘘です。

自分のコードからmy_sprintfに電話して、プラットフォームにいつもしたことをさせてください。

+0

この回答は質問に対処していません。問題は、すでにライブラリコードにコンパイルされたコードで動作するドロップイン置換を求めることです。 APIフックが必要です。 (いいえ、事実の不正確さのために下降し、質問された質問には反応しません) – IInspectable

+1

事実の正確さのためにちょうどupvoted。ネット+8をお楽しみください。 (実際には、OPが聞きたいことではないにしても、これは正しい答えだと思います。)そして@IInspectable、APIフックは悪い考えであり、静的にリンクされたDLL内のRTLなどでは動作しません。 – CherryDT

+0

@IInspectable:答えは「これをしないでください」であるため、質問に答えます。 –

1

あなたがvariadic functions.

例を使用します。これは未定義の動作です。

sprintfへのすべての通話を、カスタムのmy_sprintf機能に置き換える必要があります。

+0

はいOPにする必要がありますが、私は "どのように私はこの機能を実装する"とは思わない質問があった。この関数をstdlibの '' sprintf''を "オーバーライド"させる方法です( '#define'とその疑問文を見てください)。 –

+0

@ LightnessRacesinOrbit Shoot、あなたは正しいです。これは '#define'は未定義の動作です。私はまだこれがまた質問に答えると思う、コードOPの掲載が正しくないので。 – Leandros

+0

@LightnessRacesinOrbitまだ免責事項が追加されています。 – Leandros

0

あなたはすでに答え/コメントからもわかるように、おそらく非常にあいまいな方法があり、

char buffer[256]; 
myns::sprintf(buffer, "Hello, %s!\n", "World"); 
+0

残念ながら、これは実際の問題を解決するものではありません。 "しかし、私はまだすべての用途をカバーすることができないと心配しています。あるものは事前ビルドされたライブラリ**にあります。 – CherryDT

+0

@CherryDT:あなたの場合、唯一の方法は標準のCライブラリを再定義することです。しかし、それは良い選択ではありません。 – Mykola

+0

**事前ビルドされたライブラリでは実行できない**リンクが静的な場合に備えて、リンクされているRTLを遡及的に変更することはできません。(はい、あなたはFLIRTのような署名に基づいて関数を識別し、ロードされたときにDLLの中に関数をフックすることができると知っていますが、今は地獄への道が本当にあります) – CherryDT

関連する問題