views:

130

answers:

1

Lets say I have this class in foobar-shared.lib:

class FooBar {
    std::string m_helloWorld;
}

And I have a call in foobar-from.exe using SendCopyData like so:

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);
}

When from a foobar-to.exe, I handle OnCopyData:

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

This worked fine when FooBar was a struct, but now that it's a class I get this error:

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

I assumed originally that this was because my fooBar instance is on the stack, so I tried moving it to the heap but got a slightly different error (I can post the result here if necessary).

According to MSDN, "The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data." so I suspect that this only possible with struct data. Am I correct?

+2  A: 

you are both correct and incorrect.

your problem here is that you don't know the implementation details of std::string. unfortunately, it seems this (standard) class uses a dynamicaly allocated buffer to store its character data. that's why WM_COPYDATA doesn't work with it.

but if your class does not contain a pointer to any external data, as suggested in the documentation, then it would be perfectly valid to copy it using WM_COPYDATA. unfortunately, this greatly limits the possible types for members of your class.

(think WM_COPYDATA is like sending data over a network: you should take care of serializing your class before sending it out in the wild...)

Adrien Plisson