С Новым годом! Форум программистов, компьютерный форум, киберфорум
FASM
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.95/21: Рейтинг темы: голосов - 21, средняя оценка - 4.95
0 / 0 / 0
Регистрация: 03.11.2015
Сообщений: 4

Не получается получить данные из динамической библиотеки, написанной на FASM...

20.08.2017, 18:47. Показов 4396. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Не получается получить данные из Java, в dll написанной FASMом, изменить что-нибудь и отправить обратно в Java.
Использовал пример: C-Java ( outofrange.ru/2015/02/jni-tutorial/ )

Код Java:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class HelloJNI {
    private native int[] sumAndAverage(int[] numbers);
 
    static  
   {
       System.load("d:/MasDll.dll");
    }
    public static void main(String[] args) {
       int[] numbers = {123, 234, 345};
       Int[] results = new HelloJNI().sumAndAverage(numbers);
       System.out.println("In Java, the sum is " + results[0]);
       System.out.println("In Java, the average is " + results[1]);
    }
}
Код Fasm:

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
format PE GUI 4.0 DLL   ;Формат исполняемого файла DLL
entry hwEntry                  ;Инициализация DLL. Функция DllEntryPoint
include 'win32ax.inc'     ;Нужна для создания DLL.
 
  ;Этот макрос возвращает указатель на таблицу функций в fnTblPtr
   macro GetFnTblPtr envPtr, fnTblPtr
   {
    mov ebx, [envPtr]      ;envPtr адрес таблицы функций
    mov eax, [ebx]
    mov [fnTblPtr], eax
   }
 
  ;Этот макрос возвращает указатель на нужную функцию
   macro GetFnPtr fnTblPtr, index, fnPtr
   {
    mov eax, index          ;Номер функции
    mov ebx, 4                 ;Делитель
    mul ebx                      ;Умножает номер функции на 4 (размер функции 4 байта)
    mov ebx, [fnTblPtr]   ;Указатель на таблицу функций
    add ebx, eax              ;Добавляет к началу таблицы функций номер нужной
    mov eax, [ebx]
    mov [fnPtr], eax        ;FnPtr = адрес нужной функции
   }
 
section ".data" data readable writable
  Caption  db 'Native',0
  Message1 db 'Данные обнаруженны',0
  Message2 db 'Данные отсутствуют',0
 
section '.text' code readable executable
 
  proc hwEntry hinstDLL,fdwReason,lpvReserved
    mov eax, TRUE
    ret
  endp
 
 
proc Java_HelloJNI_sumAndAverage JNIEnv, jobject, jintArray
  local fnptr             :DWORD   ;Адрес нужной JNI функции
  local fntblptr        :DWORD   ;Указатель на таблицу функций
  local JavaMas     :DWORD   ;Полученный массив
  local LengthMas :DWORD   ;Полученная длина массива
  local OutMas       :DWORD   ;Массив для отправки в Java. Ни знаю какой должен быть размер в FASM.
 
  ;Вызовы макросов с передачей параметров
  GetFnTblPtr JNIEnv, fntblptr     ;Возвращает указатель на таблицу функций в fnTblPtr
  GetFnPtr fntblptr, 187, fnptr      ;187 - GetIntArrayElements
 
  ;GetIntArrayElements
   push 0                           ;3-isCopy
   push [jintArray]            ;2-Строковый объект Java
   push [JNIEnv]               ;1-Указатель интерфейса JNI
  call [fnptr]                       ;Вызов JNI функции GetIntArrayElements
   mov [JavaMas], eax    ;Сохраняет указатель на элементы массива (возвращает не 0)
 
 ;GetArrayLength
  GetFnPtr fntblptr, 171, fnptr    ;Макрос
   push [jintArray]                  ;Указатель на элементы массива
   push [JNIEnv]                     ;Указатель интерфейса JNI
  call [fnptr]                             ;Конвертирует массив, возвращает количество элементов массива
   mov [LengthMas], eax      ;Длина массива (возвращает 3)
 
 
;--- Проверка наличия данных в массиве ---
    cmp [JavaMas], 123    ;123 Первый элемент массива Java
     jne m0
    invoke MessageBox, 0, addr Message1, Caption, 0   ;Есть
    jmp m1
m0: invoke MessageBox, 0, addr Message2, Caption, 0   ;Нету
m1:
    ;При запуске java проекта выводится сообщение Message2 (123 нету)
;-------- Конец проверки ---------
 
;ReleaseIntArrayElements
  GetFnPtr fntblptr, 195, fnptr    ;Макрос
   push 0                     ;4-Mode
   push [JavaMas]     ;3-Указатель на массив элементов
   push [jintArray]      ;2-Объект массива Java
   push [JNIEnv]         ;1-Указатель интерфейса JNI
  call [fnptr]                 ;Нативный код больше не нуждается в доступе к elems (Возвращает не 0)
                                     ;При необходимости, эта функция копирует все изменения, внесённые elems в исходный массив.
 
;NewIntArray()
  GetFnPtr fntblptr,179, fnptr   ;Макрос
   push [LengthMas]      ;2-Длина массива
   push [JNIEnv]              ;1-Указатель интерфейса JNI
   call [fnptr]                     ;Возвращает массив Java
   mov [OutMas],eax
 
;SetIntArrayRegion
  GetFnPtr fntblptr, 211, fnptr   ;Макрос
   push [jintArray]        ;5-Исходный буфер
   push [LengthMas]   ;4-Число элементов, которые будут скопированы
   push 0                       ;3-Начальный индекс
   push [OutMas]         ;2-Массив Java
   push [JNIEnv]          ;1-Указатель интерфейса JNI
   call [fnptr]                 ;Копирует обратно область примитивного массива из буфера.   
 
 ;После вызова SetIntArrayRegion функции,  Java пишет:
  ;Exception in thread “Main” java.lang.NullPointerException
  ;          at HelloJNI.sumAndAverage(Native Method)
  ;          at HelloJNI.main(HelloJNI.java:12)
ret
endp
 
section '.idata' import data readable writeable
  library kernel, 'KERNEL32.DLL', user, 'USER32.DLL'
  import user, MessageBox, 'MessageBoxA'
 
section 'edata' export data readable
 export 'MasDll.DLL', \
  Java_HelloJNI_sumAndAverage,'Java_HelloJNI_sumAndAverage'             
 
section '.reloc' fixups data discardable
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.08.2017, 18:47
Ответы с готовыми решениями:

Не получается вызвать функцию из простейшей библиотеки, написанной на C++
Братва, спасай! Я уже все волосы с груди содрал! Создал новую библиотеку, чистую, чтоб уж наверняка, там создал функцию, которая...

Вызов функции одной динамической библиотеки из другой динамической библиотеки
Добрый день! Помогите пожалуйста разобраться со следующим вопросом. Возможно ли из одной библиотеки передать параметры для...

Почему не передаются данные из динамической библиотеки?
Когда я возвращаю указатель из функции, программа получает его вместе с данными. Динамическая библиотека: __declspec(dllexport) RGBQUAD...

7
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6809 / 2049 / 238
Регистрация: 14.12.2014
Сообщений: 4,300
Записей в блоге: 12
21.08.2017, 12:24
Что значит "не получается"? Как выглядит это "не получается"?
Ещё знать бы как Java передаёт параметры...

Добавлено через 10 минут
И каков формат массива? Скорее всего это не просто список элементов (тогда иначе где брать размер массива?)
Как возвращается результат, если это массива? И т.д.
Т.е. нужно ковыряться в этом всём.
0
0 / 0 / 0
Регистрация: 03.11.2015
Сообщений: 4
21.08.2017, 13:23  [ТС]
После вызова двух JNI (Java Native Interface) функций: GetIntArrayElement ( возвращает тело примитивного массива. У меня в JavaMas) и GetArrayLength (конвертирует массив и возвращает количество элементов. У меня в переменной LengthMas). Вроде посредством двух переменных с адресом массива и его размера, можно работать с полученным массивом. В переменной LengthMas лежит тройка (три элемента массива), все вроде правильно, но в переменной JavaMas нету первого элемента 123, который я передавал из явы
но вроде должен быть, и нуля тоже нету (ошибка).
Вот, ни получается, получить или использовать эти переменные с указателем на массив и его размером.
Ява передаёт параметры через стек. Первый это указатель на массив Jni параметров "JNIenv". Второй на какой-то объект.
Третий на массив Java который на прямую прочитать нельзя, нужно использовать JNI функции из явы. Я их и использую, но первый элемент массива не вижу, да и другие тоже.
Массив выглядит так: 123, 234, 345 (dword). Размер массива получает JNI функция "GetArrayLength" (3).
Результат работы функции GetIntArrayElement в регистре eax (указатель на элементы полученного массива)
0
4189 / 1837 / 220
Регистрация: 06.10.2010
Сообщений: 4,124
07.09.2017, 12:47
9900
Посмотрел мельком. Вроде бы для вызова функций Java в FASM нужно использовать макросы interface и cominvk. Почитаю про Java - отпишусь.
0
4189 / 1837 / 220
Регистрация: 06.10.2010
Сообщений: 4,124
07.09.2017, 16:43
Лучший ответ Сообщение было отмечено ФедосеевПавел как решение

Решение

Ты не правильно обращаешься к массиву
Assembler
1
cmp [JavaMas], 123
Надо так
Assembler
1
2
mov eax,[JavaMas]
cmp dword[eax], 123
Во вложении пример с использованием cominvk
Вложения
Тип файла: 7z JNI.7z (3.4 Кб, 10 просмотров)
1
0 / 0 / 0
Регистрация: 03.11.2015
Сообщений: 4
07.09.2017, 20:51  [ТС]
Привет murderer.
Изменил обращение к полученному массиву, и проверка сообщила о найденных данных!
Макросы в начале кода рабочие.
Спасибо за помощь!

Но вот обратно этот массив отправить в Java не удаётся, посредством вызова трёх последних JNI функций, после проверки.
Java пишет:
Exception in thread "main" java.long.NullPointerException
at HelloJNI.sumAndAverage(Native Method)
at HelloJNI.main(HelloJNI.java:12)

Может параметры неправильные ввожу?
0
4189 / 1837 / 220
Регистрация: 06.10.2010
Сообщений: 4,124
08.09.2017, 09:45
Лучший ответ Сообщение было отмечено ФедосеевПавел как решение

Решение

Макросы в начале кода рабочие.
Они, конечно, рабочие, но выполняют лишнюю работу для вычисления смещения в таблице указателей. При использовании cominvk смещения вычисляются на этапе компиляции (можешь сравнить дизассемблированный код для интереса).

Добавлено через 8 минут
Насчёт ошибки - похоже ты вначале вызываешь ReleaseIntArrayElements, а затем обращаешься к этому уже недействительному указателю через SetIntArrayRegion и Java вполне правомерно выдаёт exception.

Добавлено через 53 минуты
Нужно возвращать указатель на созданый массив через регистр eax.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
proc Java_HelloJNI_sumAndAverage __JNIEnv: DWORD, jobject, jintArray
  local elem rd 1
  local len  rd 1
 
  virtual at __JNIEnv
  _JNIEnv JNIEnv
  end virtual
 
  cominvk _JNIEnv,GetIntArrayElements,[jintArray],0
  mov     [elem],eax
  cominvk _JNIEnv,GetArrayLength,[jintArray]
  mov     [len],eax
  cominvk _JNIEnv,NewIntArray,eax
  push    eax
  cominvk _JNIEnv,SetIntArrayRegion,eax,0,[len],[elem]
  cominvk _JNIEnv,ReleaseIntArrayElements,[jintArray],[elem],2
  pop     eax
 
ret
  call [MessageBoxW] ;Без этого не создаётся таблица импорта и Java не хочет загружать DLL
endp
Описание интерфейса возьмёшь из архива, который я выкладывал ранее. Ну или на оффсайте.
1
0 / 0 / 0
Регистрация: 03.11.2015
Сообщений: 4
08.09.2017, 14:55  [ТС]
Взял пример из архива, списал вызовы JNI функций (указанные выше), и все заработало!
Большое спасибо murderer!
Ответ получен!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.09.2017, 14:55
Помогаю со студенческими работами здесь

Подключение библиотеки, написанной на C++
Здравствуйте. Пытаюсь подключить свою dll.dll написанную на С++. Подключаю на C#. Это читал: ...

Использование библиотеки, написанной на Delphi
Здравствуйте, нужно написать длл библиотеку на делфи, и использовать ее в c#, не подскажите простой пример? Как ни делал по примерам из...

Использование библиотеки, написанной на ассемблере
Я написал библиотеку на ассемблере, которая складывает два числа. Загружаю ее в Delphi и использую функцию из библиотеки. Ввожу значения: 1...

Почему не получается получить данные из БД?
Что я делаю не так??? как правильно сделать выборку??? В БД есть 2 одинаковые таблицы tab1 и tab2 нужно если ip из таблицы tab2 совпадают...

Не получается получить данные из массива
person.h #include <iostream> #pragma once class Person { public: Person(); Person(char *data_name); ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru