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 менялись данные переменных, так что мой вопрос все еще остается без ответа, может ли кто-нибудь помочь мне понять это? К сожалению, только моя ошибка была устранена

Другие вопросы по тегам