2

32 ビット製品を 64 ビット製品に変換しようとすると問題が発生します。Visual Studio 2008 を使用しており、コードは C および C++ です。次の 2 行のコードを見ていただきたいと思います。1 行は C ソース ファイルからのもので、もう 1 行は C++ ソース ファイルからのものです。これらのファイルは両方とも DLL に含まれています。両方のコード行の逆アセンブルも含めます。

ewxlcom.c

memcpy(pCM->pSecAccInfo->spUserID,userSecurityInfo.spUserID,
     sizeof(UserID));
000000000EF33BB9  mov         r8d,80h 
000000000EF33BBF  mov         rdx,qword ptr [rsp+828h] 
000000000EF33BC7  mov         rcx,qword ptr [rsp+1F8h] 
000000000EF33BCF  mov         rcx,qword ptr [rcx+0BDEh] 
000000000EF33BD6  call        memcpy (0EF40352h) 

tcputil.cpp

memcpy(serv_temp+INIT_MSG_USERID_OFFSET, pCM->pSecAccInfo->spUserID, INIT_MSG_USERID_LEN);
000000000EF3B8E6  lea         rcx,[rsp+67h] 
000000000EF3B8EB  mov         r8d,80h 
000000000EF3B8F1  mov         rdx,qword ptr [rsp+3B0h] 
000000000EF3B8F9  mov         rdx,qword ptr [rdx+0CBEh] 
000000000EF3B900  call        memcpy (0EF40352h) 

ご覧のとおり、最初の行は、 が指すメモリにいくつかのバイトをコピーしますpCM->pSecAccInfo->spUserID。そして 2 行目は、同じバイトをメモリ内の別の場所にコピーします。ASMは、 registerが指すメモリからregister がmemcpy指すメモリにバイトをコピーします。そのため、最初の行で値が register に移動されます。これは を指していることを確認しました。次に、 が指す値が にコピーされます。と呼ばれます。これは機能します。rdxrcxrcxpCMrcx + 0BDEhrcxmemcpy

しかし、その後の 2 行目で、値が register にロードされrdxます。pCMこれは、最初の行と同じものを指すことも確認しました。pCM次に、 ( rdx)から だけオフセットされたメモリに常駐するポインタをロードします0CBEh。そのメモリはすべてゼロなので、memcpyクラッシュします。

問題は、コンパイラが同じソース変数に対して異なるコードを生成する理由です。アライメントの問題だと思います。CファイルとC++ファイルの違いですか?VS は C と C++ の両方に同じコンパイラを使用しますか? 他に見るべきものはありますか?

どんな助けでも大歓迎です。

4

1 に答える 1

1

C & C++ コードをリンクしている場合は、構造体のさまざまなパディング特性に注意する必要がある場合があります。おそらく、構造体の各メンバーのオフセットを出力する一時関数を作成し、同じコードを C ソース ファイル (記述した場所) から C++ ソース ファイルにコピーします。関数の 2 つのコピーは同じままでかまいません。C++ のコピーが破損するためです。ただし、それぞれの先頭に printf() を追加して、どのバージョンであるかを示します。次に、クラッシュ前のどこかからそれぞれを呼び出して、オフセットを比較できるようにします。それらが異なる場合は、その問題を解決するためにコンパイラ フラグを調べる必要があります。または...おそらく、次のような行を追加する必要があります...

#ifdef __cplusplus
extern "C" {
#endif
 .
 .    ...your struct definitions & variables go here...
 .
#ifdef __cplusplus
}
#endif

...構造体定義の周りで、C++ 側がプロジェクトの C 側と同じパディング動作を持つようにします。

于 2012-12-05T00:55:10.280 に答える