0

重複の可能性:
Cでの##プリプロセッサの使用は何ですか

Fun with Google TTSから... 誰でもこのコードがどのように機能しているかを明らかにできますか? 特に「c##_」とはどのような表記ですか?-

#define DsHook(a,b,c) if (!c##_) { 
INT_PTR* p=b+*(INT_PTR**)a;  VirtualProtect(&c##_,4,PAGE_EXECUTE_READWRITE,&no);
*(INT_PTR*)&c##_=*p;  VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no);  *p=(INT_PTR)c;

コードで次のように展開されます-

//  redirect  7th member func of IAsyncReader (SyncReadAlligned) to grab mp3 data from output pin of source filter
DsHook(reader,6,SyncReadAlligned); 

メモリをいじるにはあまり安全な方法ではないと思いますが、著者は「重要ではない」とコメントしています。

フックのような重要でないコードはスニペット形式で折りたたまれていますが、自由に展開して好きなようにコードをフォーマットしてください。

PS "Fun with Google" 自体は、Google によって既にブロックされている場合 (誰かがテストに興味がある場合)。

更新:簡単な分析は次のようになると思います-「ソースフィルターの出力ピンから mp3 データを取得するために IAsyncReader (SyncReadAlligned) の 7 番目のメンバー関数をリダイレクトする」ために、コミットされたページの特定の領域のメモリ保護を「何でも」から変更しますwas" を PAGE_EXECUTE_READWRITE に変更します (フル アクセスを許可します)。

そして安全性についてMSDNは言う -

VirtualProtect を使用して、GlobalAlloc、HeapAlloc、または LocalAlloc によって割り当てられたメモリ ブロックのページ保護を変更しないことをお勧めします。これは、1 つのページに複数のメモリ ブロックが存在する可能性があるためです。... 実行可能になる領域を保護する場合、呼び出しプログラムはキャッシュの一貫性を確保する責任を負います...

4

2 に答える 2

5

「連結」を意味するプリプロセッサ ディレクティブです。引数の置換値とリテラル文字c##_を含むトークンになります。例:c_

#define foo(c) c##_

を使用して呼び出すとfoo(bar)、これは に展開されbar_ます。

于 2013-01-15T07:40:20.167 に答える
2

この表記法##は、マクロ定義、つまり連結において特別な意味を持ちます。ここでc##_c をアンダースコアと連結して、新しい token を形成しますc_。ここで c は引数であることに注意してください。したがってhereIAm、マクロに引数として渡すと、展開後はc##_になりhereIAm_ます。

于 2013-01-15T07:41:52.590 に答える