【发布时间】:2021-10-18 00:12:20
【问题描述】:
我正在尝试将字符串从 Java(第一个应用程序)发送到 c++(第二个带有仅消息窗口的应用程序)。
首先,我尝试的是: 我将this example 改编到我的代码中,并在 java 端得到了这个
STRMSG msg = new STRMSG();
msg.message = "test";
//msg.write(); // Idk exactly why because i thought JNA does this before every call. Works the same without
cds = new COPYDATASTRUCT();
cds.dwData = new ULONG_PTR(UniqueWindowMessageID);
cds.cbData = msg.size();
cds.lpData = msg.getPointer();
cds.write(); // But here it is somehow needed because otherwise the message will not arrive.
JNA.USER32.INSTANCE.SendMessage(
msgOnlyWnd, WinUser.WM_COPYDATA,
null,
new LPARAM(Pointer.nativeValue(cds.getPointer()))
);
哦,STRMSG 看起来像这样(也改编自示例):
public class STRMSG extends Structure {
public STRMSG() {
super();
}
public STRMSG(Pointer p) {
super(p);
read();
}
public String message;
protected List<String> getFieldOrder() {
return Arrays.asList("message");
}
}
在 c++ 端,我得到了仅消息窗口,并且可以成功捕获 WM_COPYDATA 消息。
但不知何故,我的 String 值在这里是空的:
case WM_COPYDATA: {
PCOPYDATASTRUCT cds = (PCOPYDATASTRUCT)lParam;
if (cds->dwData == UniqueWindowMessageID) { // <- works
STRMSG* msgStruct = (STRMSG*)cds->lpData; // <- The message struct is corrupt i guess
cout << msgStruct->message << endl; // Will just endl in the console
}
break;
}
这是c++端的结构:
const struct STRMSG {
string message;
};
除了这个尝试之外,我还尝试调整我的结构,使其包含一个 BYTE* (byte[]) 和大小,以便我可以使用以下字节和大小创建一个字符串:(source)
std::string s(reinterpret_cast<char const*>(inputParam), lengthParam);
但是我的结构无论如何都不是它应该的样子。所以数据在某种程度上是错误的,并且 IDK 我在这里做错了什么。
感谢任何帮助。
编辑:我还在调试时查看了数据。我什么都没得到:
EDIT2:
Remy 评论后,我的 COPYDATASTRUCT 看起来像这样:
byte[] msg = "test".getBytes();
cds = new COPYDATASTRUCT();
cds.dwData = new ULONG_PTR(UniqueWindowMessageID);
cds.cbData = msg.length;
cds.lpData = msg // how??
cds.write();
但是我应该如何将cds.lpData 映射到byte[]?
【问题讨论】:
-
我们已经在您的previous question 中介绍了这一点。您的 Java 代码犯了与您的 C++ 代码相同的错误。您只发送
STRMSG结构,而不是它指向的字符串数据。现在您正在使问题复杂化,因为 Java 代码正在发送 Java 的string类型,它与 C++ 的std::string类型不兼容。完全没有理由在这段代码中使用STRMSG结构,所以去掉它。让 Java 代码将string编码为byte[]数组,然后WM_COPYDATA可以将这些字节发送到 C++ -
天哪……你说得对。会尝试。我被 JNA 的例子蒙蔽了双眼。
-
@RemyLebeau 好的,基本上在完全删除结构之后。如何将
cds.lpData(即Pointer)映射到byte[]? (我也更新了问题) -
关于您的评论问题:当将结构作为参数传递给本机方法时,JNA 会自动编写结构。但你永远不会通过那个。因此,您正在为
STRMSG分配本机内存并获取指向它的指针,但从不将您的 String 写入它。无论如何,您都会丢失分配,因此即使写入也无法正常工作。
标签: java c++ winapi jna sendmessage