나는 (Win32 API에 대한 호출 : 데이터를 저장하기 위해 WM_COPYDATA와 COPYDATASTRUCT를 가진 SendMessage를) 작동시키기 위해 많은 노력을 기울 였고, 지금 나의 윈도우 7 컴퓨터에서 작동하므로, 나의 매핑이 좋은지 궁금하다. 내 솔루션의 부작용이 없다면? , 중요한 것은 내가 인터넷에서 발견 한 모든 것을 비교하여이 코드JNA : COPYDATASTRUCT에 대한 올바른 매핑은 무엇입니까?
User32Extension.COPYDATASTRUCT.ByReference dataStruct = new User32Extension.COPYDATASTRUCT.ByReference();
String message = "Hello ! :-) !";
Memory m = new Memory(message.length() + 1);
m.setString(0, message);
dataStruct.dwData = 10;
dataStruct.cbData = message.length() + 1;
dataStruct.lpData = m;
dataStruct.write(); // writes to native memory the structure.
result = user32.SendMessage(hwndTarget, // target hwnd.
User32Extension.WM_COPYDATA, // copy data message.
wparam, // current hwnd
dataStruct // data by reference here
);
User32Extension.COPYDATASTRUCT.ByReference myDataStruct = new User32Extension.COPYDATASTRUCT.ByReference();
User32Extension.TEST_STRUCT myStruct = new User32Extension.TEST_STRUCT();
//simple C structure here with 4 fields of C types int, char, char and long.
myStruct.iNumber = 677;
myStruct.cCode = 'E';
myStruct.cCode2 = 'T';
myStruct.lLong1 = new NativeLong(123456789L);
myStruct.write();
LOGGER.trace("myStruct (size=" + myStruct.size() + ")=" + myStruct.toString(true));
myDataStruct.dwData = 11;
myDataStruct.cbData = myStruct.size();
myDataStruct.lpData = myStruct.getPointer();
myDataStruct.write(); // writes to native memory the structure.
result = user32.SendMessage(hwndTarget, // target hwnd.
User32Extension.WM_COPYDATA, // copy data message.
wparam, // current hwnd
myDataStruct // data
);
그 COPYDATASTRUCT입니다 :
/**
* For usage with WM_COPYDATA
* cf : https://msdn.microsoft.com/en-us/library/windows/desktop/ms649010(v=vs.85).aspx
*/
long SendMessage(HWND hWnd, int msg, WPARAM wParam, COPYDATASTRUCT.ByReference lParam);
int WM_COPYDATA = 0x004A;
//cf : https://msdn.microsoft.com/en-us/library/windows/desktop/ms649010(v=vs.85).aspx
class COPYDATASTRUCT extends Structure {
public static class ByReference extends COPYDATASTRUCT implements Structure.ByReference {
}
public COPYDATASTRUCT() {
super();
}
public int dwData;
public long cbData;
public Pointer lpData;
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "dwData", "cbData", "lpData" });
}
}
그리고이 개 예제와 함께 호출 코드 : 여기
내 코드입니다 속성 cbData 유형이 long입니다. int로 설정하면 작동하지 않습니다 (데이터가 레거시 C 응용 프로그램의 WndProc에서 올바르게 수신되지 않음). DWORD를 긴 java 유형에 매핑하는 것이 맞습니까? NativeLong으로 더 좋을까요?주목해야 할 또 다른 것은 모든 인스턴스화 된 구조체 (myStruct 및 myDataStruct)에 대한 Structure.write()를 명시 적으로 호출 한 것입니다. SendMessage API를 호출하기 전에 빈 메모리가 필요하지 않습니다. 정상이라고 생각하십니까? 아니면 jna SendMessage 호출하기 전에 자동으로 호출해야합니까?
미리 감사드립니다.
JNA는 'DWORD'및 기타 창 유형에 대한 정의를 제공합니다. 네이티브'long '타입의 사용은 JNA의'NativeLong' 타입으로 표현되어야합니다. 'Structure.write()'는 구조체 인수를 가진 네이티브 함수 호출 전에 JNA에 의해 자동으로 호출됩니다. – technomage
@technomage, 필자는 또 다른 테스트를했다. 올바른 동작을 위해 반드시 필요한 것은 아니다. 나는'Structure.toString (true)'에 대한 호출과 함께 디버깅을 위해 그것을 추가했다. DWORD 형식에 대해 사용하는 경우 메시지가 C라는 프로그램에 도착하지 않습니다. – cnico7
다음은 정보를위한 것입니다 (Hello 문자열 테스트를위한) 메모리 덤프입니다 : DWORD가있는 메모리 덤프 cbData는 : 는 [0a000000] [0e000000] [00c2d058] [00000000] 메모리 cbData 긴로 덤프 : [0a000000] [00000000] [0e000000] [00000000] [306eda58] [00000000 ] – cnico7