powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Обращение к экземпляру TForm на с++
9 сообщений из 9, страница 1 из 1
Обращение к экземпляру TForm на с++
    #38987720
ViktorOff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, уважаемые форумчане!
Ввиду небольшого опыта работы в Java уповаю на вашу помощь.
Задача: в коде на Java обратиться к экземпляру Класса с++ наследника TForm. Пробую использовать JNI.
В коде на Java храню переменную nativeHandle (получаю в методе TestJNIForm.initialise()), где находится указатель на экземпляр созданной формы в с++.
В процедуре getForm вытаскиваю ее из Java и привожу к TForm.

Код: plaintext
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.
//---------------------------------------------------------------------------
 
TForm *getForm(JNIEnv *env, jobject obj)
{
    jfieldID HandleField= env->GetFieldID(env->GetObjectClass(obj), "nativeHandle", "J");
    jlong handle = env->GetLongField(obj, HandleField);
    return reinterpret_cast<TForm *>(handle);
}
//---------------------------------------------------------------------------
 
jlong JNICALL Java_my_TestJNIForm_initialise(JNIEnv *, jobject)
{
    TForm *form=new TForm(Application);
    form->Caption="1";
    return (jlong)form;
}
//---------------------------------------------------------------------------
 
void JNICALL Java_my_TestJNIForm_show(JNIEnv *env, jobject obj)
{
    TForm *form = getForm(env, obj);
    form->Show();
}
//---------------------------------------------------------------------------
 
jint JNICALL Java_my_TestJNIForm_getVal(JNIEnv *env, jobject obj)
{
    TForm *form = getForm(env, obj);
    return StrToInt(form->Caption);
}
//---------------------------------------------------------------------------
 
void JNICALL Java_my_TestJNIForm_setVal(JNIEnv *env, jobject obj, jint val)
{
    TForm *form = getForm(env, obj);
    form->Caption=IntToStr(val);
}
//---------------------------------------------------------------------------



Проблема заключается в следующем. Если в Java-коде вызываю метод TestJNIForm.show(), то форма показывается и подвисает. Если вызываю ее в отдельном процессе, то она показывается на мгновение и закрывается. Если в с-коде использовать ShowModal, то отображается нормально, но взаимодействие недоступно. (Взаимодействие для простоты условно реализовано в методах TestJNIForm.setVal(), TestJNIForm.getVal(), изменение заголовка формы, в численном виде, чтобы не отвлекаться на работу со строками)
В англоязычном секторе интернета нашел пост, где чел интересовался проблемой один в один с этой, но ему никто не ответил. Буду очень признателен за любые мысли по данному поводу.
...
Рейтинг: 0 / 0
Обращение к экземпляру TForm на с++
    #38987963
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IMHO я так понимаю вопрос про Borland C ? Какой версии ?

ViktorOffПроблема заключается в следующем. Если в Java-коде вызываю метод TestJNIForm.show(), то форма показывается и подвисает.

ViktorOffЕсли вызываю ее в отдельном процессе, то она показывается на мгновение и закрывается.
Что есть "отдельный процесс"?

ViktorOffЕсли в с-коде использовать ShowModal, то отображается нормально, но взаимодействие недоступно. (Взаимодействие для простоты условно реализовано в методах TestJNIForm.setVal(), TestJNIForm.getVal(), изменение заголовка формы, в численном виде, чтобы не отвлекаться на работу со строками)
Тут я вообще перестал понимать. Что значит в "с-коде" ? Где и с кем ты хочешь взаимодействовать ?

В общем-то это и логично. Ты же делаешь ShowModal, пока форму не закроют, управление возвращаться не должно.

IMHO & AFAIK
1 + 2 проблема - какая то дребедень с обработкой очереди сообщений. Читать доку про TApplication и TForm.showModal(). Я бы первым делом вместо модального окна использовал бы обычное + ручками запускал метод TApplication занимающийся выгребанием сообщений из очереди сообщений Windows. IMHO & AFAIK

Доки на енбаркадере не нашел, т.ч. ни проверить предположение, ни точнее подсказать не смогу.
...
Рейтинг: 0 / 0
Обращение к экземпляру TForm на с++
    #38988320
ViktorOff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1. Версия Borland C++ Builder 6.
2. Извиняюсь, имел в виду "потоке"

Код: java
1.
2.
3.
4.
5.
6.
7.
new Thread(new Runnable() {
                    @Override
                    public void run() {
                        setVal(7);
                        show();
                    }
                }).start();



3. ShowModal, это я к слову упомянул, что при нем форма показывается без подвисания.
Проблема как раз в том, что при показе в немодальном режиме в одном потоке с основным кодом на java, (как и хотелось бы) форма подвисает. Соответственно тут уже не до очереди сообщений, а если запустить в отдельном, форма откроется и закроется.
Взаимодействие имелось в виду следующее. В программе на java вызывается нативный метод setVal, а в dll на с++ свойство Caption у формы заполняется этим значением. Если есть желание, там пару файликов с кодом прикручены, очень мало кода.
...
Рейтинг: 0 / 0
Обращение к экземпляру TForm на с++
    #38988480
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ViktorOff3. ShowModal, это я к слову упомянул, что при нем форма показывается без подвисания.
Проблема как раз в том, что при показе в немодальном режиме в одном потоке с основным кодом на java, (как и хотелось бы) форма подвисает. Соответственно тут уже не до очереди сообщений, а если запустить в отдельном, форма откроется и закроется.

Опять ничего не понял.

Т.е. я так понимаю:
1) при ShowModal в "главном потоке" все работает?

2) Проблема исключительно в запуске в отдельном от главного потоке?

Код: java
1.
2.
3.
4.
5.
6.
7.
new Thread(new Runnable() {
                    @Override
                    public void run() {
                        setVal(7);
                        show();
                    }
                }).start();


IMHO Как-то сильно МАЛО кода. Попытайся тут же, в ЭТОМ потоке (в РАБОЧЕМ) и создавать объект. Подозреваю проблема в том, что TApplication был проинициализирован в другом потоке, а обработку пытаешься запускать в данном. Соответственно какие-то структуры "не попали".

Подозреваю, что ИНИЦИАЛИЗАЦИЯ TApplication (т.е. твое СОЗДАНИЕ экземпляра Java объекта) и собственно РАБОТА ( showModal() ) должно быть в ОДНОМ потоке (не важно в каком).
ViktorOffЕсли есть желание, там пару файликов с кодом прикручены, очень мало кода.
Дело не только в желании, но и в отсутствие Borland C. Мне и MS VS на компьютере хватает ))).

Взаимодействие для простоты условно реализовано в методах TestJNIForm.setVal(), TestJNIForm.getVal(),

В случае разных потоков, я бы предложил "взаимодействовать" тупо через сообщения Windows.

Т.к. IMHO синхронизироваться нужно/придется в C-ном коде, а там это не настолько просто, как на Java + похоже будет нужно вклинивать синхронизацию в обработку очереди сообщений (showModal). Подозреваю, стандартный showModal никакой синхронизации не имеет.
...
Рейтинг: 0 / 0
Обращение к экземпляру TForm на с++
    #38989247
ViktorOff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Возможно, я излагаю проблему достаточно путанно. Убрал все лишнее.
Из java вызываю нативный метод для показа vcl формы.

Код: java
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.
package my;

import javax.swing.JFrame;

public class TestJNIForm {

    public TestJNIForm() {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        showVCLForm();
    }

    public static void main(String[] args) {
        new TestJNIForm();
    }

    static {
        System.loadLibrary("JNIForm");
    }

    private native void showVCLForm();
}



В dll на Borland c builder 6 реализую метод вызова vcl формы.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
//---------------------------------------------------------------------------

void JNICALL Java_my_TestJNIForm_showVCLForm(JNIEnv *, jobject)
{
    TForm *form=new TForm(Application);
    form->Show();
}
//---------------------------------------------------------------------------



Запускаю программу, форма показалась, но увы, висит. Есть мысли, что не так?
...
Рейтинг: 0 / 0
Обращение к экземпляру TForm на с++
    #38989651
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ViktorOffЕсть мысли, что не так?
Show() замени на ShowModal(). Цикл выборки сообщений крутить некому.
...
Рейтинг: 0 / 0
Обращение к экземпляру TForm на с++
    #38989747
ViktorOff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
C ShowModal() отображается нормально, только уже не обратишься к свойствам формы, т.к. модальный режим. Значит с Show() никак, без вариантов?
...
Рейтинг: 0 / 0
Обращение к экземпляру TForm на с++
    #38989803
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ViktorOffC ShowModal() отображается нормально, только уже не обратишься к свойствам формы, т.к. модальный режим. Значит с Show() никак, без вариантов?
Почему никак. Кто то же должен разгребать очередь сообщений Windows. Или ShowModal
или можно заюзать соответствующие методы в TApplication (что правильнее).

В данном случае, у Вас концептуально не правильно реализована система. Если Вы действительно хотите _паралельного_ выполнения, то тогда так и делайте, в двух
потоках:
1. Один поток A - Java
2. Второй поток B - C код (окно + цикл разгребания сообщений Windows) + Java обертка
Вообще, функционал во втором потоке лучше реализовывать переопределяя не TForm, а TApplication AFAIK.

Понятно, что "просто обращаться к свойства" объекта в другом потоке - категорически нельзя. Т.к. нужно как-то синхронизироваться. Проще всего. что бы не париться с синхронизацией, "общаться" через сообщения Windows.

После создания окна, запоминаете его Handle и в классе окна на Borland C пишите обработчик на свои сообщения Windows.

#define MYMSG_GET_PROPERTY ( WM_USER+1 )
#define MYMSG_SET_PROPERTY ( WM_USER+2 )

https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644931(v=vs.85).aspx

Соответственно, когда нужно установить/получить свойство, в другом потоке дергаете:
SendMessage( my_wnd, MYMSG_SET_PROPERTY, 0, my_value ) etc....

IMHO Через сообщения Windows самое простое.

https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644950(v=vs.85).aspx
...
Рейтинг: 0 / 0
Обращение к экземпляру TForm на с++
    #38989819
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Написал и засомневался... можно или нет так... Давно на Windows API не писал. Но судя по доке, должно работать. Если я правильно понял, каждый поток создавший окно, получает свою персональную очередь сообщений.

https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644928(v=vs.85).aspx
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Обращение к экземпляру TForm на с++
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]