Сопоставление функции c ++ с JNA - PullRequest
1 голос
/ 30 апреля 2020

У меня проблема при попытке сопоставить эту функцию c ++ с JNA.

https://www.inventcom.net/fanuc-focas-library/program/cnc_rdexecprog

FWLIBAPI short WINAPI cnc_rdexecprog(unsigned short FlibHndl, unsigned short *length, short *blknum, char *data);

Я пытался с этими сопоставлениями в java, но не работает:

short cnc_rdexecprog(short FlibHndl, ShortByReference length, ShortByReference blknum, String data);
short cnc_rdexecprog(short FlibHndl, ShortByReference length, ShortByReference blknum, Pointer data);
short cnc_rdexecprog(short FlibHndl, ShortByReference length, ShortByReference blknum, Memory data);

Первое отображение работает, но возвращает ту же строку, которую я отправляю, второе и третье показывает эту ошибку:

Exception in thread "AWT-EventQueue-0" java.lang.Error: Invalid memory access

Мне удалось получить аналогичные функции работая благодаря этой теме: Используйте C ++ DLL из Java с JNA

Я думаю, что проблема в выходном параметре "char * data". Как отобразить эту функцию?

1 Ответ

0 голосов
/ 30 апреля 2020

Тип char * ожидает буфер байтов (символов в C). Тип

Java String является неизменяемым (const char *), поэтому нативный код не может его изменить, как вы заметили. Тип Pointer будет работать, но, как видно из сообщения об ошибке, не указывает на выделенную память. Memory также работает (и расширяет Pointer), но требует от вас фактического выделения памяти вашим параметром. Например:

Memory buffer = new Memory(bufferSize);

Вы можете передать buffer как Pointer или Memory в ваш метод, и он будет работать.

Проблема здесь заключается в определении значения bufferSize должно быть Вот где API услужливо сообщает вам:

length [in / out] Укажите адрес переменной, которая показывает количество символов для чтения. Установите количество символов для чтения этой переменной * длина (длина). После прочтения количество фактически прочитанных символов снова задается в этой переменной * length (длина).

Вам необходимо согласовать размер буфера и длину, передаваемую во втором аргументе. Обратитесь к документации, чтобы узнать, существует ли какая-либо константа, определяющая максимальную длину ожидаемой строки, и используйте ее. (Исходя из этого примера , это может быть MAX_PROG_SIZE (1024 * 2), с дополнительным байтом, добавленным для нулевого терминатора. Но вы должны проверить это сами.)

Если это не существует, стандартная идиома JNA:

  • Объявите размер и передайте его собственной функции (длина и выделенный буфер должны совпадать)
  • Проверка кода результата, указывающего вы не указали достаточное количество символов (вероятно, EW_LENGTH (2))
  • Повторите с большим буфером, пока строка не будет соответствовать.

В качестве альтернативы вы можете начать с гораздо большего значения .

Во всех случаях не забудьте добавить 1 к фактической максимальной длине строки, чтобы учесть нулевой терминатор.

...