2016-06-23 7 views
2

私は2つのモジュールを持っています。 1つは他の1つを呼び出し、引数として構造体を渡します。引数としてポインタをスレーブDLLに渡すオブジェクトのサイズが間違っています

struct { 
    char* szDGRTag; 
    bool bTagEx; 
} ADPTAG; 

マスターは、Visual C++ 6.0で'98からC++で書かれています。スレーブはVisual Studio 2010 ProfessionalのC++ 11で書かれています。スレーブで呼び出され
機能:マスターで

long lCheckPresenceOfFields (char* szName, ADPTAG* AdpTagList, long lNbVar) 

long lNbVar = 2; 
ADPTAG* AdpTagList = NULL; 
AdpTagList = new ADPTAG[lNbVar]; 

AdpTagList[0].szTag = new char[32]; 
AdpTagList[0].bTagEx = true; 
memset(AdpTagList[0].szTag, 0x0, 32+1); 
AdpTagList[0].szTag = NULL; 

AdpTagList[1].szTag = new char[32]; 
AdpTagList[1].bTagEx = true; 
memset(AdpTagList[1].szTag, 0x0, 32+1); 
AdpTagList[1].szTag = NULL; 

int size = sizeof(AdpTagList[0]); 
AdpTagList[0].szTag = "DDD"; 
AdpTagList[1].szTag = "AAA"; 

long pres = pGetFieldsPresence(szPath, AdpTagList, 2); 

私はマスターにAdpTagListのサイズ[0]を確認したのだが、5つのバイトだったが、スレーブにそれが8であります最初のオブジェクトはOKですが、ポインタが間違ったメモリ領域を指しているため、次のオブジェクトは不良です。
ここで問題になるのは何ですか?別のコンパイラ?おそらく、char *とintのみの構造体はこれら2つのモジュール間でうまく動作しません。
第1オブジェクト[0]のサイズにかかわらず、第2 [1]はヌルポインタです。

+0

[sizeof(bool)は定義されていますか?](http://stackoverflow.com/questions/4897844/is-sizeofbool-defined) – GSerg

+0

これはどのように役立ちますか?両方のモジュールのboolのsizeofが1、両方のモジュールのchar *のサイズが4です。vc6のオブジェクトのサイズは5で、vs2010のサイズは8 –

+1

です。次に、.hファイルで定義されている異なるパディングでなければなりません。 – GSerg

答えて

3

パッケージの不一致が発生しています。 "/Zp" compiler optionで梱包を変更することができます。

デフォルトのVisual Studioによるので:8バイト境界上の

パック構造

それはあなたのVisual Studio 2010のコンパイラは、パッキンを指定していない可能性が非常に高いです。 Visual C++ 6.0アプリケーションは、intcharを含む構造体として1バイトパッキングを指定していた可能性があります。

1バイトパッキングを使用すると、パディングに失われたメモリがないため、プログラムシステムのメモリフットプリントが最適化されます。

8バイトパッキングを使用すると、単一の負荷で構造をフェッチできる可能性が高くなるため、速度を最適化します。 https://msdn.microsoft.com/en-us/library/71kf49f1.aspx

をしかし、私は、Microsoftの声明でいいと思う:あなたはここで読むことができます梱包の詳細について

あなたが特定の配置要件

を持っていない限り、あなたは、このオプションを使用しないでください

これは、1つを変更する必要があるため、Visual C++ 6.0アプリケーションのパッキングを変更することをお勧めします。

+0

スレーブモジュールは多くのマスターと共に使用されます。ですから、最良の選択肢は、パディングなしで8バイトにコンパイルするchar *とintを使うことです。 1,2,4,8バイトのストラクチャーメンバーアライメントを持つマスターには互換性があります。しかし、16歳ではないかもしれませんが、私はそのような場合はないと仮定することができます。どう思いますか? –

+0

@MarekCzaplicki私は編集しましたが、私の好みはVisual C++ 6.0のアラインメントを修正することです。あなたはメモリフットプリントを心配しているなら、いつでももっと多くのRAMを買うことができます。あなたは決してもっと時間を買うことはできません。 –

+0

ええ、これは私にとって、他のすべてのマスターモジュールがこのパディングについてチェックされなければならないことを意味します。 –

2

はい、それは非難するコンパイラの違いです。バイナリレベルのC++には標準化はありません。特にこれは、任意のコンパイラが構造体のための独自のパディング規則を自由に選択できることを意味します。これがここであなたに影響します。明らかに、最近のコンパイラは3バイトのパディングを追加して構造体を64ビットに整列させることにしましたが、古いコンパイラではこれを行いません。

一般に、2つの異なるコンパイラによって生成されたデータ間のバイナリ互換性を保証する方法はありません。バイトストリームを使用するように切り替えることも、両方のために同じコンパイラを使用することもできます。

関連する問題