在 JNA 中使用 WM_COPYDATA 发送字符串值时为空字符串
Empty String when sending a String value using WM_COPYDATA in JNA
我正在尝试将字符串从 Java(第一个应用程序)发送到 C++(第二个应用程序,仅包含消息 window)。
所以首先,我尝试的是:
我将 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++ 端,我只收到消息 window,我可以成功捕获 WM_COPYDATA 消息。
但不知何故,我的字符串值在这里为空:
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);
但我的结构无论如何都不是它应该的样子。所以数据有点错误,我知道我在这里做错了什么。
感谢任何帮助。
编辑:我在调试时也查看了数据。我没有得到任何东西:
编辑 2:
评论 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[]
?
好吧,基本上,在 Remy Lebeau
的帮助下(一如既往),我设法将 NativeString
Class
包含在我的项目中,这使我能够获得 [= NativeString
的 15=] 并直接在我的 COPYDATASTRUCT
.
中使用它
我不得不 inline
我自己的一些方法内容 NativeString
Class
因为其中一些也不可见。
无论如何,这是我用来构建我的 COPYDATASTRUCT
发送部分没有改变的片段。
NativeString ns = new NativeString("Hello String", true); //true so its a wide string
cds = new COPYDATASTRUCT();
cds.dwData = new ULONG_PTR(UniqueWindowMessageID);
cds.cbData = ns.length()*2; //Without *2 the text will be only the half
cds.lpData = ns.getPointer();
cds.write();
这就是我在 C++ 端处理收到的 WM_COPYDATA 消息的方式:
case WM_COPYDATA: {
PCOPYDATASTRUCT cds = (PCOPYDATASTRUCT)lParam;
if (cds->dwData == UniqueWindowMessageID) {
wchar_t* msg = (wchar_t*)cds->lpData;
wcout << msg << endl;
}
break;
}
再次感谢@Remy Lebeau
我正在尝试将字符串从 Java(第一个应用程序)发送到 C++(第二个应用程序,仅包含消息 window)。
所以首先,我尝试的是: 我将 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++ 端,我只收到消息 window,我可以成功捕获 WM_COPYDATA 消息。
但不知何故,我的字符串值在这里为空:
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);
但我的结构无论如何都不是它应该的样子。所以数据有点错误,我知道我在这里做错了什么。
感谢任何帮助。
编辑:我在调试时也查看了数据。我没有得到任何东西:
编辑 2:
评论 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[]
?
好吧,基本上,在 Remy Lebeau
的帮助下(一如既往),我设法将 NativeString
Class
包含在我的项目中,这使我能够获得 [= NativeString
的 15=] 并直接在我的 COPYDATASTRUCT
.
我不得不 inline
我自己的一些方法内容 NativeString
Class
因为其中一些也不可见。
无论如何,这是我用来构建我的 COPYDATASTRUCT
发送部分没有改变的片段。
NativeString ns = new NativeString("Hello String", true); //true so its a wide string
cds = new COPYDATASTRUCT();
cds.dwData = new ULONG_PTR(UniqueWindowMessageID);
cds.cbData = ns.length()*2; //Without *2 the text will be only the half
cds.lpData = ns.getPointer();
cds.write();
这就是我在 C++ 端处理收到的 WM_COPYDATA 消息的方式:
case WM_COPYDATA: {
PCOPYDATASTRUCT cds = (PCOPYDATASTRUCT)lParam;
if (cds->dwData == UniqueWindowMessageID) {
wchar_t* msg = (wchar_t*)cds->lpData;
wcout << msg << endl;
}
break;
}
再次感谢@Remy Lebeau