7 / 7 / 1
Регистрация: 20.12.2010
Сообщений: 392
1

Межпроцессное взаимодествие (анонимный канал и WM_COPYDATA)

24.01.2017, 12:59. Показов 602. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Есть матрица типа int**, с которой необходимо произвести следующие действия:
1) Отправить другому приложению (серверу) для обработки, используя анонимный канал
2) Вернуть преобразованную матрицу исходному приложению (клиенту), используя сообщение WM_COPYDATA

Что, собственно, пытаюсь делать:
1)
Создание анонимного канала и отправка матрицы на сервер:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DWORD dwWritten;
HANDLE hRead, hWrite;
SECURITY_ATTRIBUTES saAttr;
    
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);  
 
CreatePipe(&hRead, &hWrite, &saAttr, 0));
hPipe = CreateFile(L"Client", GENERIC_READ | GENERIC_WRITE, 0, &saAttr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hPipe, initial_matrix, sizeof(int) * N * N, &dwWritten, NULL); //initial_matrix - "готовая" матрица, N - размерность
CloseHandle(hWrite);
 
SendMessage(FindWindow(L"Server", NULL), WM_RECV_FROM_KLIENT, NULL, NULL);
 
CloseHandle(hPipe);
Попытка "приёма" матрицы на сервере:
C++
1
2
3
4
5
6
7
8
9
10
case WM_RECV_FROM_KLIENT:
    CreatePipe(&hRead, &hWrite, &saAttr, 0);
    hPipe = CreateFile(L"Client", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
    if (!ReadFile(hPipe, initial_matrix, sizeof(int) * N * N, &dwRead, NULL)) 
    {
        MessageBox(NULL, L"Ошибка чтения файла!", L"Ошибка", MB_OK | MB_ICONERROR);
        return;
    }
    ...
Собственно, "Ошибка чтения файла!"...Хочу понять, в чём проблема и как её можно было бы решить

2)
Пытаюсь "вернуть" клиенту новую матрицу, заполненную единицами(раз уж исходную принять не получается):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct Matrix
{
    int size;
    int **result_matrix;
} New_Matrix;
...
COPYDATASTRUCT MyCDS;
MyCDS.dwData = 1;
New_Matrix new_matrix;
new_matrix.result_matrix = initial_matrix;//забегая вперёд отмечу, что матрица проинициализирована правильно
new_matrix.size = N;//размерность
MyCDS.cbData = sizeof(new_matrix);
MyCDS.lpData = &new_matrix;
SendMessage(FindWindow(L"Client", NULL), WM_COPYDATA, (WPARAM)(HWND) hWnd, (LPARAM)(LPVOID) &MyCDS);
В итоге обрабатываю полученную матрицу на клиенте:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
typedef struct Matrix
{
    int size;
    int **result_matrix;
} New_Matrix;
...
PCOPYDATASTRUCT pMyCDS;
...
case WM_COPYDATA:
    pMyCDS = (PCOPYDATASTRUCT) lParam;
 
    switch(pMyCDS->dwData)
    {
        case 1:
        New_Matrix new_matrix;
            new_matrix.result_matrix = ((New_Matrix *) (pMyCDS->lpData))->result_matrix;
        new_matrix.size = ((New_Matrix *) (pMyCDS->lpData))->size;
            //и теперь самое интересное
            sprintf_s(tmp, "%d  ", new_matrix.size);//РАБОТАЕТ
        MessageBoxA(hWnd, tmp, "Размер", MB_OK | MB_ICONINFORMATION);
            sprintf_s(tmp, "%d  ", new_matrix.result_matrix[0][0]);//НЕ РАБОТАЕТ
        MessageBoxA(hWnd, tmp, "Элемент", MB_OK | MB_ICONINFORMATION);
            ...
По всей видимости, я просто неправильно пытаюсь считать двумерный массив, ведь попытки просмотреть его контрольные значения при отладке говорят о том, что "Чтение памяти невозможно", при том, что размерность(new_matrix.size) считывается нормально

Буду рад любой помощи по этим двум вопросам.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.01.2017, 12:59
Ответы с готовыми решениями:

Связь через анонимный канал в направлении от одного потомка к другому
Добрый день, может кто нибудь написать простейший пример псевдокода (Win API) связи через анонимный...

Взаимодествие с кнопками
Приветствую всех! Помогите разобраться вот в таком вопросе: есть 3 кнопки: <form...

Взаимодествие Lotusscript и Java
Как свести два языка? Напрмер LS может получить значение по средствам языка формул используя...

Взаимодествие jsp с сервлетом
У меня в jsp есть текстовое поле c id='inputStr',хочу оттуда ее переслать в сервлет response.java и...

6
Эксперт С++
3070 / 1408 / 425
Регистрация: 19.01.2009
Сообщений: 3,866
24.01.2017, 21:03 2
Цитата Сообщение от Кротяка Посмотреть сообщение
Собственно, "Ошибка чтения файла!"...Хочу понять, в чём проблема и как её можно было бы решить
После ошибки в ReadFile() вызовите GetLastError() чтобы узнать причины.

Цитата Сообщение от Кротяка Посмотреть сообщение
C
1
2
3
4
5
6
MyCDS.dwData = 1;
New_Matrix new_matrix;
new_matrix.result_matrix = initial_matrix;//забегая вперёд отмечу, что матрица проинициализирована правильно
new_matrix.size = N;//размерность
MyCDS.cbData = sizeof(new_matrix);
MyCDS.lpData = &new_matrix;
Так вы передаете sizeof(new_matrix) байт с указателями на int внутри процесса сервара, для процесса клинта эти укзатели будут указывать на мусор. Нужно собрать все int числа, чтобы они последовательно шли друг за другом, для чего потребуется N * M * sizeof(int) байт. В cbData должно быть это число, а в lpData указатель на N*M целых чисел идущих в памяти последовательно, друг за другом.
0
7 / 7 / 1
Регистрация: 20.12.2010
Сообщений: 392
25.01.2017, 00:25  [ТС] 3
schdub, спасибо за отклик.
После ошибки в ReadFile() вызовите GetLastError() чтобы узнать причины.
Дело в том, что я не совсем понимаю, как правильно использовать анонимные каналы, потому как материала по этой теме в сети немного, и его исследование мало что дало. Собственно, за этим вопросом я и обратился сюда, попутно указав, чего удалось достичь. GetLastError() возвращает ошибку с кодом 6(ERROR_INVALID_HANDLE), указывающую на неверный дескриптор.

Что касается второго пункта - можете изобразить наглядно?(если не тяжело)
0
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
25.01.2017, 13:36 4
Цитата Сообщение от Кротяка Посмотреть сообщение
Дело в том, что я не совсем понимаю, как ...
Кротяка, зачем сразу вместе собирать все непонятные вопросы? Можно разобраться отдельно.

C++
1
2
int mesg[5]={ 10, 20, 30, 40, 50 };
// попробуем отправить mesg по анонимному каналу.
Добавлено через 35 минут
Цитата Сообщение от Кротяка Посмотреть сообщение
C++
1
2
hPipe = CreateFile(L"Client", ... 
WriteFile(hPipe, ...
Кротяка, здесь вы записываете что-то в файл Client.
0
7 / 7 / 1
Регистрация: 20.12.2010
Сообщений: 392
25.01.2017, 13:40  [ТС] 5
Alex5, ну вопроса то всего 2 (как правильно передать данные через анонимный канал и как вернуть эти данные при помощи WM_COPYDATA), и т.к. они взаимосвязаны, то потому и спрашиваю в одной теме
0
1130 / 789 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
25.01.2017, 15:18 6

Не по теме:

Цитата Сообщение от Кротяка Посмотреть сообщение
ну вопроса то всего 2
Кротяка, судя по коду, есть еще вопросы, с которыми стоит разобраться. Что такое указатель. Чем отличаются int**, int[N][N].
Если непонятно, чем int** отличается от массива, не нужно его использовать в этом примере.



Добавлено через 36 минут
Цитата Сообщение от Кротяка Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
typedef struct Matrix
{
 int size;
 int **result_matrix;
} New_Matrix;
...
 
COPYDATASTRUCT MyCDS;
MyCDS.dwData = 1;
New_Matrix new_matrix;
new_matrix.result_matrix = initial_matrix;//забегая вперёд отмечу, что матрица проинициализирована правильно
Как проинициализирована initial_matrix?

C++
1
2
new_matrix.size = N;//размерность
MyCDS.cbData = sizeof(new_matrix);
Кротяка, пусть N=100. Сколько байт данных в этом случае нужно передать клиенту ? Чему равняется sizeof(new_matrix) ?
0
7 / 7 / 1
Регистрация: 20.12.2010
Сообщений: 392
25.01.2017, 16:07  [ТС] 7
Alex5,
Как проинициализирована initial_matrix?
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
double Q, x;
int N;
 
N = 8;
Q = 0.5;
 
initial_matrix = new int*[N];
 
for (int i = 0; i < N; i++)
    initial_matrix[i] = new int[N];
 
srand((unsigned)time(0));
 
for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++)
    {
        x = (double)(rand()) / RAND_MAX;
 
        if (x >= Q)
            initial_matrix[i][j] = 1;
        else
            if (x < Q)
                initial_matrix[i][j] = 0;
    }
0
25.01.2017, 16:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.01.2017, 16:07
Помогаю со студенческими работами здесь

Полевый транзисторы N канал и P канал
Здравствуйте. Обьясните пожалуйста по управлению полевыми транзисторами Как я понимаю...

4-х канал 1866 vs 2-х канал 2133
Здравствуйте, нигде не нашел информации по этому вопросу, может кто знает из вас, что будет...

К реке шириной a м построен под прямым углом канал шириной b м. Какой максимальной длины суда могут входить в этот канал
...канал* Как это можно решить?

Wm_CopyData
Поправьте ошибку вроде все правильно сделал но при передачи сообщения в конце появляются не...

WM_COPYDATA между С++ и С#
Здравствуйте. Есть win 2003 sp2 terminal server. Коммуникация между win прогами С++ и С# с помощью...

Получение сообщения WM_COPYDATA
Собственно задача Нужно отправить определённой программе команду с помощью...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru