Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
2 / 2 / 2
Регистрация: 23.03.2016
Сообщений: 142

Одновременная передача данных в виде двух массивов через буфер обмена

22.05.2019, 10:34. Показов 2630. Ответов 28
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, пишу программу корреляционного расходомера на основе sdk виртуального осциллографа и столкнулся с проблемой одновременной передачи входящих данных с двух каналов. Проблема заключается в следующем: имеется два входящих сигнала и, соответственно, два одновременно и беспрерывно обновляющихся массива входящих данных, которые нужно одновременно передать на другое приложение для последующей обработки. Как это правильно сделать? Написал что-то подобное, но не уверен в правильности работы:
C++
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
void CHard::SourceToDisplay(USHORT* pData,ULONG nDataLen,USHORT nCH)
{
    int j = 1;
    for(ULONG i=0;i<nDataLen;i++)
    {
        *(m_pSrcData[nCH]+i) = *(pData+i)-(MAX_DATA - m_nLeverPos[nCH]);
    }
    if(OpenClipboard(NULL))
            {
                std::stringstream str;
                str << *(m_pSrcData[nCH]);
                for (j=1; j < nDataLen; j++)
                {
                    str << " " << *(m_pSrcData[nCH] + j);
                } //преобразование массива ushort в string
                std::string str2 =str.str();
                HGLOBAL hgBuffer;
         EmptyClipboard(); //очищаем буфер
         hgBuffer= GlobalAlloc(GMEM_DDESHARE, str2.size()+1);
         std::string chBuffer;
         chBuffer = (LPTSTR)GlobalLock(hgBuffer);
         chBuffer= str2;
         GlobalUnlock(hgBuffer);
         SetClipboardData(CF_TEXT, hgBuffer);
         CloseClipboard();
            }
}
Приложение, которое принимает и обрабатывает данные, еще не написано, но сразу хотел бы спросить, как лучше все это скомпоновать, можно ли написать это приложение на c# с его WPF (и как тогда правильно связать со вторым приложением)? В данном приложении должна будет быть кнопка, по нажатию которой запускается второй проект и начинается прием данных с осциллографа и передача их на первый проект.
Используется Visual Studio 2010.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.05.2019, 10:34
Ответы с готовыми решениями:

Передача файла через буфер обмена RDP и его запуск
вот код он входит в rdp надо добавить в него что бы он после входа брал файл передавал его в rdp на раб стол запускал #include...

Копирование через буфер обмена из 2х полей формы и вставка данных в другую форму
Всем очень добрый день! Подскажите пожалуйста, можно ли реализовать одновременное копирование данных из 2-х полей формы и вставку этих...

Буфер обмена(получение и передача информации)
Всем привет. Мне необходимо получить данные из буфера обмена(данные могут быть любые, картинка, текст, объекты различных приложений т.е....

28
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
08.06.2019, 21:22
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от narsky Посмотреть сообщение
CreateProcess
Второй аргумент может редактироваться функцией, а ты передаешь туда константу. Не понимаю, как это у тебя вообще скомпилировалось.
0
2 / 2 / 2
Регистрация: 23.03.2016
Сообщений: 142
08.06.2019, 21:32  [ТС]
nonedark2008, функцией? Я так понял, данный параметр как-то связан с командной строкой, но как именно - я не смог понять и что туда вписывать.
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
08.06.2019, 21:39
narsky, ну так все досконально описано в документации к функции CreateProcess:

lpCommandLine

The maximum length of this string is 32,768 characters, including the Unicode terminating null character. If lpApplicationName is NULL, the module name portion of lpCommandLine is limited to MAX_PATH characters.

The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.

If both lpApplicationName and lpCommandLine are non-NULL, the null-terminated string pointed to by lpApplicationName specifies the module to execute, and the null-terminated string pointed to by lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first token in the command line.

If lpApplicationName is NULL, the first white space–delimited token of the command line specifies the module name. If you are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension, or if the file name contains a path, .exe is not appended.
1
2 / 2 / 2
Регистрация: 23.03.2016
Сообщений: 142
08.06.2019, 21:48  [ТС]
nonedark2008, Поместил путь на место первой переменной, второй присвоив значение NULL, и все заработало странно, я и до этого так пытался сделать, но только сейчас все заработало
0
2 / 2 / 2
Регистрация: 23.03.2016
Сообщений: 142
09.06.2019, 08:24  [ТС]
А как можно запустить данный процесс, чтобы он работал сам по себе неограниченно долго, и чтобы приложение, создающее процесс, не ждало от него ответа об окончании данного процесса?

Добавлено через 7 минут
Или ждало бесконечно долго (процесс будет оканчиваться нажатием кнопки), но при этом оба приложения работали параллельно и продолжали обмениваться данными?
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
09.06.2019, 09:04
Цитата Сообщение от narsky Посмотреть сообщение
чтобы приложение, создающее процесс, не ждало от него ответа об окончании данного процесса?
Удали
Цитата Сообщение от narsky Посмотреть сообщение
C++
1
WaitForSingleObject( pi.hProcess, INFINITE );
0
2 / 2 / 2
Регистрация: 23.03.2016
Сообщений: 142
09.06.2019, 14:39  [ТС]
nonedark2008, спасибо, заработало я и раньше также пытался сделать, но в тот момент из-за дальнейшего кода не работало так, как нужно
А теперь вопрос, как завершить данный процесс и закрыть окно нового приложения?
Сейчас у меня примерно такая структура кнопки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CreateProcess( dd,   // the path
    NULL,        // Command line
    NULL,           // Process handle not inheritable
    NULL,           // Thread handle not inheritable
    FALSE,          // Set handle inheritance to FALSE
    0,              // No creation flags
    NULL,           // Use parent environment block
    NULL,           // Use parent starting directory 
    &si,            // Pointer to STARTUPINFO structure
    &pi             // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
    );
..... // бесконечный цикл while, который будет останавливаться по нажатию на другую кнопку
CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
}
Т.е. по идее, последние две команды должны останавливать и поток, и процесс, правильно?
Не помог даже
C++
1
TerminateProcess(pi.hProcess, 0);
В будущем планирую в первом приложении по необходимости завершения работы второго приложения создать новый пайп, который пошлет какую-нибудь переменную второму приложению, вызывающую exitprocess().

Добавлено через 4 минуты
но если оставить лишь один TerminateProcess, то процесс закрывается как по щелчку, т.е. нужно поиграться со структурами si и pi, чтобы после
C++
1
2
CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
дополнительно еще и закрывать окно второго процесса? Или как это работает?

Добавлено через 4 часа 14 минут
Передача массивов по-прежнему проходит странно (метка не обновляются, не исключено, что проблема именно в реализации фонового потока backgroundworker). В приложении 1 по нажатию кнопки запускается фоновый backgroundworker, в котором создается pipe (канал успешно создается), а затем с помощью бесконечного цикла осуществляется передача данных, однако не выходит сообщение об установлении связи с приложением 2 (скриншот ниже), а сообщение о принятии данных (скриншот 2) выходит только один раз. Может быть где-то нарушена логика включения пайпа или дело во втором приложении? Немного о его логике: прибор считывает данные раз в определенный промежуток времени, затем запускает пару функций, в последней из которых запускается функция readData, в которой происходит считывание данных, затем создается файл для пайпа и туда записываются данные, после чего функция завершает работу. Может ли неудачная передача данных связана с тем, что функция readData вызывается из раза в раз (и не с помощью цикла, а посредством определенной проверки работоспобности устройства) и, соответственно, как-либо перезаписывает файл или что-то вроде того?
Первое приложение:
C++
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
//...
public: delegate void dShowResult(String^);
//...
CreateProcess( dd,   // the path
    NULL,        // Command line
    NULL,           // Process handle not inheritable
    NULL,           // Thread handle not inheritable
    FALSE,          // Set handle inheritance to FALSE
    0,              // No creation flags
    NULL,           // Use parent environment block
    NULL,           // Use parent starting directory 
    &si,            // Pointer to STARTUPINFO structure
    &pi             // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
    );
 
  backgroundWorker1->RunWorkerAsync();
}
private: System::Void Stop_Click(System::Object^  sender, System::EventArgs^  e) {
             this->backgroundWorker1->CancelAsync();
             Stop->Enabled = false;
             
         }
private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {
             
             
    HANDLE   hNamedPipe;
    DWORD   dwBytesRead;
    DWORD   dwBytesWritten;
    hNamedPipe = CreateNamedPipe(
    L"\\\\.\\pipe\\signalpipe",  // имя канала
    PIPE_ACCESS_DUPLEX,        // читаем из канала и пишем в канал
    PIPE_TYPE_MESSAGE | PIPE_WAIT,   // синхронная передача сообщений
    1,         // максимальное количество экземпляров канала 
    0,         // размер выходного буфера по умолчанию
    0,         // размер входного буфера по умолчанию
    INFINITE,  // клиент ждет связь бесконечно долго
    NULL       // безопасность по умолчанию
    );
    if (hNamedPipe==INVALID_HANDLE_VALUE)
  {
                String^ str1 = gcnew String(GetLastErrorAsString().c_str());
        MessageBox::Show(str1);
  }
    else
        MessageBox::Show("Канал создан!");
 
    
    while(1)
    {
        if(!ConnectNamedPipe(
                    hNamedPipe,    // дескриптор канала
                    NULL      // связь синхронная
                 ))
                 {
                      String^ str3 = gcnew String(GetLastErrorAsString().c_str());
                  MessageBox::Show(str3);
              }
         else
                    MessageBox::Show("Связь установлена!");
    
         USHORT* rreadData[4096];
             for (int i = 0; i < 4; i++)
                  rreadData[i] = new USHORT[4096];
    
        
                for (int i = 0; i < 4; i++)
                {
                      if(!ReadFile(
                           hNamedPipe,      // дескриптор канала
                            rreadData[i],      // данные
                           4096*sizeof(USHORT),  // размер данных
                           &dwBytesRead,    // количество записанных байтов
                         NULL))
    
                   {
                      String^ str3 = gcnew String(GetLastErrorAsString().c_str());
                      MessageBox::Show(str3);
                    }
                   else
                    MessageBox::Show("Данные получены");
                          }
 
           String^ message =gcnew String(rreadData[0][0].ToString());
          dShowResult^ d = gcnew dShowResult(this, &Form1::showResult);
 
                 if (this->InvokeRequired)
                     this->Invoke(d, message);
                 
    
             for (int i = 0; i < 4; i++)
                 delete rreadData[i];
    
        }
       }
 private: System::Void showResult(String^ message)
{
 
             this->label7->Text = message;
}
Второе:
C++
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
void CHard::ReadData()
{
    int i=0;
    
    USHORT* pReadData[MAX_CH_NUM];
    for(i=0;i<MAX_CH_NUM;i++)
    {
        pReadData[i] = new USHORT[m_stControl.nReadDataLen];
        memset(pReadData[i],0,m_stControl.nReadDataLen*sizeof(USHORT));//
    }
    m_nReadOK = dsoHTGetData(m_nDeviceIndex,pReadData[CH1],pReadData[CH2],pReadData[CH3],pReadData[CH4],&m_stControl);//считывание данных
    
    if(m_nReadOK == 1)
    {
        for(i=0;i<MAX_CH_NUM;i++){
            
            LPCSTR hpipe = "\\\\.\\pipe\\signalpipe";
            DWORD dwBytesWritten;
    hNamedPipe = CreateFile(
    hpipe,          // имя канала
    GENERIC_READ | GENERIC_WRITE,       // читаем и записываем в канал
    FILE_SHARE_READ | FILE_SHARE_WRITE, // разрешаем чтение и запись 
    NULL,                  // безопасность по умолчанию
    OPEN_EXISTING,         // открываем существующий канал
    FILE_ATTRIBUTE_NORMAL, // атрибуты по умолчанию
    NULL);
    
    WriteFile(
    hNamedPipe,      // дескриптор канала
    pReadData[i],      // данные
    4096*sizeof(USHORT),  // размер данных
    &dwBytesWritten,    // количество записанных байтов
    NULL);
 
        }
        
    }
    
    for(i=0;i<MAX_CH_NUM;i++)
    {
        delete pReadData[i];
    }
}
0
2 / 2 / 2
Регистрация: 23.03.2016
Сообщений: 142
09.06.2019, 14:41  [ТС]
скрины
Миниатюры
Одновременная передача данных в виде двух массивов через буфер обмена   Одновременная передача данных в виде двух массивов через буфер обмена  
0
2 / 2 / 2
Регистрация: 23.03.2016
Сообщений: 142
09.06.2019, 19:27  [ТС]
Передача данных работает, достаточно было один раз инициализировать канал пайпа при инициализации приложения во втором приложении, ну и соответственно один раз на на первом приложении

Добавлено через 1 час 51 минуту
Все вопросы уже не актуальны, успешная попытка связи по второму каналу пайпа успешно закрывает второе приложение)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.06.2019, 19:27
Помогаю со студенческими работами здесь

Передача параметра в буфер обмена c JavaScript
Пользовательская форма вызывается по щелчку на веб-странице. Эта форма с кнопками написана на JavaScript. Необходимо по нажатию на кнопку...

Передача данных в виде структуры через ClientSocket
Проблема заключается в том что нужно передать структурный тип данных struct zakaz { AnsiString Surname; AnsiString Name; ...

Сохранение кнопок через буфер обмена
Помогите разобраться пожалуйста суть задачи такова,по нажатию на форму,создаются кнопки (button),в скоре через меню нужно сохранить эти...

Копирование файла через буфер обмена
С текстом все просто: https://www.cyberforum.ru/vb-net/thread364372.html Как быть с файлом?

Одновременная передача и прием данных
Здравствуйте! При попытки передать и получить данные одновременно, возникает проблема, т.е. при получении часть данных теряется string s...


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

Или воспользуйтесь поиском по форуму:
29
Ответ Создать тему
Новые блоги и статьи
FSharp: interface of module
DevAlt 16.05.2026
Интерфейс модуля F# позволяет управлять доступностью членов, содержащихся в реализации модуля. По-умолчанию все члены модуля доступны: module Foo let x = 10 let boo () = printfn "boo" . . .
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible". . .
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru