2016-05-24 20 views
-1

LinuxでCPUIDを取得するコードを探していて、いくつかの良い例がありました。これらは実装の違いの間に具体的な質問です。以下は、符号なし整数であり、4は、以下に示すように、size_t型と同じ出力を得るために12reinterpret_castの有無にかかわらず文字列に変換

struct CPUVendorID{ 
unsigned int ebx; 
unsigned int edx; 
unsigned int ecx; 

string toString() const { 
    return string(reinterpret_cast<const char *>(this), 12); 
} 
}; 
... 
CPUVendorID vendorID { .ebx = ebx, .edx = edx, .ecx = ecx }; 
string vendor = vendorID.toString(); 

としてsize_t型での別のフォームをreinterpret_castは使用しています。

string vendor; 
vendor += string((const char *)&cpuID.EBX(), 4); 
vendor += string((const char *)&cpuID.EDX(), 4); 
vendor += string((const char *)&cpuID.ECX(), 4); 
cout << "CPU vendor = " << vendor << endl; 

両出力12文字の文字列。上記のreinterpret_cast文で何が起こっているのか誰かが私に説明できますか?この実装方法は非常にエレガントですが、私はその作業が明らかに4 * 3 = 12である理由はわかりません。しかし、3 ebx、edx、ecxのデータをどのように連結することができますか?

CPUの製造元ID文字列 - (そのために)EBX、EDX、ECXに保存されている12文字のASCII文字列CPUID wiki

+1

CとC++は異なる言語です!迷惑メールを使わないでください – Olaf

+0

あなたは単に 'unsigned int result [3];'と 'std :: string(reinterpret_cast (結果)、sizeof結果)'と言うことができます。 –

+0

@KerrekSBあなたの提案もうまくいきます。ありがとうございました。私はおそらくあなたの提案以来、ユーザーに依存しないので行くでしょう。しかし、最初の例が(this)ポインタを使用しているときに文字列が連結される理由を知っていますか? – itsnevertoobadtoaskforhelp

答えて

0

誰かが上記reinterpret_castは文の中で何が起こっているのか私に説明できますか?

構造体アドレスthisは、最初のメンバーのアドレスであるint ebxと一致します。以下のメンバーは同じ型であるため、それらの間にはパディングはありません。したがって、このコードではintのメンバーをint[3]の配列として扱います。

+0

私が探していたもの。簡潔に説明し、すべてを説明します。ありがとうございました。 @Kerrek SBの提案についても説明しています – itsnevertoobadtoaskforhelp

+0

パディングがないことは保証されていないことに注意してください。 –

+0

@KerrekSB構造体レイアウトとメンバーの配置には要件があり、配列のメンバー間にはパディングはないという要件があります。メンバー間で不必要な埋め込みを挿入するコンパイラをコード化する場合、私はそれを使用せず、コンパイラを避けるために積極的に友達を推薦します。言い換えれば、あなたの意見はパンダニ的に正しいかもしれないが、実際には役に立たない。 –

関連する問題