JNA: Как именно функция и ее отображение параметров происходят из Java в VC++
В Java я использую JNA для загрузки файла VC++ DLL и вызова функций внутри него, в одной функции мне нужно отправить 6 параметров, В определении функции VC++ я получаю правильные значения для первых 3 параметров, но последние 3 имеют значение '0',
2-й параметр - это байтовый массив, когда я посылаю 1024 байта, я получаю 5-й параметр bool как ложный, но когда я передаю 10 байтов, он принимается как истинный
мой прототип функции:int deviceupload(Pointer p, _byte[] data_, long startaddress, long datalength,_Boolean rt_,Pointer xyz);
Так будет ли изменение карт в зависимости от размера параметров?
или стек JNA настолько мал, что не может содержать 6 параметров? но согласно документации JNA MAX_NARGS
из Function
Значение класса 256, так что я думаю, что 6 количество параметров не проблема,
хотя 3-й и 4-й параметры имеют одинаковый тип данных, в определении функции VC++ startaddress
правильно получено, но datalength
полученное значение равно 0
так какая-нибудь идея, почему она ведет себя так странно?
2 ответа
Аргументы помещаются в "слоты" памяти в стеке. Небольшой аргумент может занять один слот или использовать один слот с другим аргументом, в то время как большой аргумент может занять два слота. Вы можете видеть, как, если вы примете маленький аргумент за большой, он сместит все последующие аргументы в неправильные позиции.
void my_func (int32 p1, int64 p2)
| |
+---------------+
| P2 (64-bit) |
+---------------+
| P2 | (P2 takes up two slots)
+---------------+
+ P1 (32-bit) |
+---------------+ <-- Top of stack
Теперь, если вы по ошибке используете 64-битное значение для P1, вы получите следующее:
| |
+---------------+
| P2 (64-bit) |
+---------------+
| P2 |
+---------------+
+ P1 (64-bit) |
+---------------+
+ P1 |
+---------------+ <-- Top of stack
Вызываемый объект (функция, которую вы вызвали) не знает, что произошел этот сдвиг, и поэтому пытается прочитать аргументы с их ожидаемых позиций. Для небольших аргументов он может получить кусок большего размера, а для больших аргументов он может получить фрагменты двух или более других аргументов.
То, что на самом деле видит вызываемый, это:
| |
+---------------+
| (P2) |
+---------------+
+ (P1) |
+---------------+
+ (P1) |
+---------------+ <-- Top of stack
Вы можете видеть, что значение, считанное для P1, фактически является только половиной большего значения, в то время как значение, считанное для P2, включает в себя другую половину P1 и половину значения, переданного как P2.
(Это объяснение несколько упрощено, но обычно показывает, как работает стек)
На самом деле моя проблема была решена, функция VC++ ожидала long, который составляет 4 байта, но в java я передавал long, который составляет 8 байтов, но согласно документации JNA VC++ long эквивалентен NativeLong в java, но мы не можем вычесть две переменные NativeLong что я должен сделать это. так что я проходил Лонг.
но позже я прошел int
(4 байта) аргументы в Java для long
(4 байта) параметров в VC++, тогда он работал правильно
но я не понял, почему другие параметры были затронуты из-за несоответствия типов данных предыдущего параметра
в моей очереди из-за startaddress
переменное совпадение типов данных datalength
менялись данные переменных, так что мой вопрос все еще остается без ответа, может ли кто-нибудь помочь мне понять это? К сожалению, только моя ошибка была устранена