0

foob​​ar-shared.lib にこのクラスがあるとしましょう:

class FooBar {
    std::string m_helloWorld;
}

そして、次のように SendCopyData を使用して foobar-from.exe を呼び出します。

extern HWND hMainWnd; // foobar-from.exe

{
FooBar fooBar;

HWND hWnd = FindAppWindow(); // foobar-to.exe
COPYDATASTRUCT cds;
cds.dwData = ('f'|('o'<<8)|('o'<<16));
cds.cbData = sizeof(FooBar);
cds.lpData = (LPVOID)fooBar;
SendCopyData(hWnd, (WPARAM)hMainWnd, (LPARAM)&cds);
}

foob​​ar-to.exe からの場合、OnCopyData を処理します。

BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) {
    if (pCopyDataStruct->dwData==('f'|('o'<<8)|('o'<<16))) {
        FooBar fooBar = *(FooBar *)pCopyDataStruct->lpData;
    }
}

これは、FooBar が構造体の場合は正常に機能しましたが、クラスになったので、次のエラーが発生します。

First-chance exception at 0x0064ef81 in foobar-to.exe: 0xC0000005: 
Access violation reading location 0x0231dd7c.

当初、これは私のfooBarインスタンスがスタック上にあるためだと思っていたので、ヒープに移動しようとしましたが、わずかに異なるエラーが発生しました (必要に応じてここに結果を投稿できます)。

MSDNによると、「渡されるデータには、データを受信するアプリケーションがアクセスできないオブジェクトへのポインターやその他の参照が含まれていてはなりません。」したがって、これは構造体データでのみ可能であると思われます。私は正しいですか?

4

1 に答える 1

2

あなたは正しいことも間違っていることもあります。

ここでの問題は、std::stringの実装の詳細がわからないことです。残念ながら、この(標準)クラスは動的に割り当てられたバッファを使用して文字データを格納しているようです。WM_COPYDATAそれがそれで動作しない理由です。

ただし、ドキュメントで提案されているように、クラスに外部データへのポインタが含まれていない場合は、を使用してクラスをコピーすることは完全に有効ですWM_COPYDATA。残念ながら、これにより、クラスのメンバーが使用できるタイプが大幅に制限されます。

WM_COPYDATAネットワークを介してデータを送信するようなものだと考えてください。実際に送信する前に、クラスのシリアル化に注意する必要があります...)

于 2009-10-31T14:55:55.353 に答える