我想使用Windows'在Java程序之间发送一个简单的字符串值。使用JNI共享库使用本机C代码进行数据复制(WM_COPYDATA
)。本质上,一个想要启动通信的Java程序可以调用一个本机方法,该方法将设置一个仅消息窗口,另一个Java程序可以通过调用本机方法(存在于同一共享库中)来获取消息。
我知道我没有消息循环而且我不知道如何实现这一点。我已经在网上看过使用WndProc
回调函数的示例,但我不知道这是否是一个合适的方法,因为这是一个仅限消息的窗口(即自从我的基于Java应用程序控制台以来没有可见的UI 。
任何有关代码的帮助都将不胜感激。
设置:
JNIEXPORT jint JNICALL Java_WindowsIPC_openDataCopy
(JNIEnv * env, jobject obj, jstring message) {
MSG msg;
WNDCLASS WndClass;
memset(&WndClass, 0, sizeof(WndClass));
WndClass.lpfnWndProc = &DefWindowProc;
WndClass.lpszClassName = L"Class";
WndClass.hInstance = GetModuleHandle(NULL);
HWND hwnd;
LPCTSTR messageString = "A message";
if (!RegisterClass(&WndClass)) {
printf("failed to register class: %d\n", GetLastError());
return -1;
}
hwnd = CreateWindowEx(0, WndClass.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
if (hwnd == NULL) {
printf("Window Creation failed: %d\n", GetLastError());
return -1;
}
while (GetMessage (&msg, NULL, 0, 0) > 0) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return 0; // success
}
尝试获取消息:
JNIEXPORT jint JNICALL Java_WindowsIPC_getDataCopyMessage
(JNIEnv * env, jobject obj) {
HWND hwnd;
hwnd = FindWindowEx (
HWND_MESSAGE,
0,
0,
0
);
LPCTSTR messageString = "A message";
COPYDATASTRUCT cds;
cds.dwData = 1;
cds.cbData = sizeof(char) * (strlen(messageString) + 1);
cds.lpData = (char*)messageString;
if (hwnd == NULL) {
printf("Couldnt find window: %d\n", GetLastError());
return -1;
} else SendMessage(hwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)(LPVOID)&cds);
LPARAM lParam;
COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;
LPCTSTR lpszString = (LPCTSTR)(pcds->lpData);
printf("%s\n", lpszString);
return 0; // success
}
答案 0 :(得分:1)
您并非要求FindWindowEx()
找到HWND_MESSAGE
创建的特定 Java_WindowsIPC_openDataCopy()
窗口。您要求它找到第一个可用的 HWND_MESSAGE
窗口,该窗口可能属于任何人。您需要在lpszClass
参数中指定所需的类名。
此外,您应使用比"Class"
更独特的类名。
在接收方,不要将DefWindowProc()
本身用于lpfnWndProc
。您需要定义自己的windowproc函数。然后,您可以实际处理收到的WM_COPYDATA
消息。将任何未处理的邮件传递给DefWindowProc()
。
尝试更像这样的事情:
LRESULT WINAPI MyWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_COPYDATA)
{
COPYDATASTRUCT* pcds = (COPYDATASTRUCT*) lParam;
if (pcds->dwData == 1)
{
LPCSTR lpszString = (LPCSTR) (pcds->lpData);
printf("%.*s\n", lpszString, pcds->cbData);
return TRUE;
}
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
JNIEXPORT jint JNICALL Java_WindowsIPC_openDataCopy
(JNIEnv * env, jobject obj, jstring message)
{
WNDCLASS WndClass;
memset(&WndClass, 0, sizeof(WndClass));
WndClass.lpfnWndProc = &MyWindowProc;
WndClass.lpszClassName = TEXT("MyWindowsIPCClass");
WndClass.hInstance = GetModuleHandle(NULL);
if (!RegisterClass(&WndClass)) {
printf("failed to register class: %d\n", GetLastError());
return -1;
}
HWND hwnd = CreateWindowEx(0, WndClass.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
if (hwnd == NULL) {
printf("Window Creation failed: %d\n", GetLastError());
return -1;
}
MSG msg;
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return 0; // success
}
JNIEXPORT jint JNICALL Java_WindowsIPC_sendDataCopyMessage
(JNIEnv * env, jobject obj)
{
HWND hwnd = FindWindowEx (HWND_MESSAGE, 0, TEXT("MyWindowsIPCClass"), 0);
if (hwnd == NULL) {
printf("Couldnt find window: %d\n", GetLastError());
return -1;
}
LPCSTR messageString = "A message";
COPYDATASTRUCT cds;
cds.dwData = 1;
cds.cbData = sizeof(char) * (strlen(messageString) + 1);
cds.lpData = messageString;
if (SendMessage(hwnd, WM_COPYDATA, 0, (LPARAM)&cds) != TRUE) {
printf("Couldnt send message\n");
return -1;
}
return 0; // success
}