16 / 0 / 0
Регистрация: 23.02.2019
Сообщений: 106
1

Работа с памятью

03.05.2019, 12:30. Показов 1631. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть приложение, которое запускает другое приложение. Нужно чтобы приложение 1 получило от приложения 2 какие-то данные (1 раз). Ни какой потоковой передачи.

Пробовал через память, но иногда возникают ошибки. Нужен 100%-й способ.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.05.2019, 12:30
Ответы с готовыми решениями:

Работа с памятью
Всем добрый день. У меня появился такой вопрос: Предположим, есть такой код: AnotherObj...

Работа с памятью
Как можно "выделить" и освободить память? нужно 2-мя способами: с помощью Си шарпа и с помощью...

Работа с памятью
Здравствуйте. Прошу скинуть любые примеры записи/чтения/редактирования данных из/в память. Заранее...

Работа с памятью
Переместить массив размерностью 16 ячеек из области памяти с начальным адресом 900 в область памяти...

13
Неадекват
1493 / 1231 / 246
Регистрация: 02.04.2010
Сообщений: 2,790
03.05.2019, 12:33 2
https://docs.microsoft.com/ru-... mework-4.8
1
16 / 0 / 0
Регистрация: 23.02.2019
Сообщений: 106
03.05.2019, 13:33  [ТС] 3
Кликните здесь для просмотра всего текста
Цитата Сообщение от freeba Посмотреть сообщение
https://docs.microsoft.com/ru-ru/dot...tframework-4.8


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


То-есть, приложение 1 создает в памяти "пустое хранилище", запускает приложение, и проверяет есть ли в хранилище информация. Приложение 2 обращается к существующему хранилищу непосредственно в память с тем же адресом и заполняет хранилище информацией.
Приложение 1 находит информацию и проводит "одноразовое" считывание, после чего "уничтожает" ранее созданное хранилище. Оба приложения имеют константу (координаты в памяти) где расположено временное хранилище.
0
Неадекват
1493 / 1231 / 246
Регистрация: 02.04.2010
Сообщений: 2,790
03.05.2019, 14:08 4
Цитата Сообщение от Zeropil Посмотреть сообщение
То-есть, приложение 1 создает в памяти "пустое хранилище", запускает приложение, и проверяет есть ли в хранилище информация. Приложение 2 обращается к существующему хранилищу непосредственно в память с тем же адресом и заполняет хранилище информацией.
Приложение 1 находит информацию и проводит "одноразовое" считывание, после чего "уничтожает" ранее созданное хранилище. Оба приложения имеют константу (координаты в памяти) где расположено временное хранилище.
Любой антивирус сочтет такую активность подозрительной. Зачем прятать факт межпроцессного обмена?
0
16 / 0 / 0
Регистрация: 23.02.2019
Сообщений: 106
03.05.2019, 15:14  [ТС] 5
Цитата Сообщение от freeba Посмотреть сообщение
Любой антивирус сочтет такую активность подозрительной. Зачем прятать факт межпроцессного обмена?
Так обмена как бы и нет, есть только считывание информации родительским приложением из дочернего. Я не хочу обращаться к процессу через ID.

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

А по поводу антивируса, пускай проверяет - это его обязанность. К тому, же, ничего "противозаконного" там нет. Если использовать критически безопасный код - никаких предупреждений антивирус не даст.

Добавлено через 6 минут
Если создавать файл физически, то он останется на диске, и при запуске приложения его придется либо удалять либо перезаписывать. В данном случае это глупо и ресурсозатратно. Ведь как мы знаем, если файл создается на диске, то он проверяется антивирусом в первую очередь, это значит, что в определенный момент времени у приложения может не быть к нему доступа. Так же, если приложение было перемещено в другое расположение, то файл останется, но его содержимое будет не ликвидным. Так же, в него могут попасть вирусы или прочая ерунда с правами доступа к файлу.
0
Неадекват
1493 / 1231 / 246
Регистрация: 02.04.2010
Сообщений: 2,790
03.05.2019, 15:26 6
В таком случае попробуйте IPC Channels, но онo посложнее в реализации чем MMF.
1
910 / 795 / 329
Регистрация: 08.02.2014
Сообщений: 2,391
03.05.2019, 15:35 7
Цитата Сообщение от Zeropil Посмотреть сообщение
Если создавать файл физически, то он останется на диске
а вы не пробовали документацию внимательнее почитать? и посмотреть что там есть метод который создаёт чисто в "памяти" без физического на диске? CreateNew, CreateOrOpen
0
16 / 0 / 0
Регистрация: 23.02.2019
Сообщений: 106
03.05.2019, 16:04  [ТС] 8
Цитата Сообщение от SeIZVeIZ Посмотреть сообщение
а вы не пробовали документацию внимательнее почитать?
Я даже читал про метод передачи между приложениями. запускается сервер, запускается клиент, в клиенте пишутся сообщения, на сервере отображаются.

Но, увы, метод предложенный там, хотя и похож, но не работает как нужно. У меня не гипертексты, мне нужно передать лишь парочку значений типов int и string. И нагружать лишними манипуляциями программу нет смысла. Нужен быстрый и безотказный метод.
0
910 / 795 / 329
Регистрация: 08.02.2014
Сообщений: 2,391
03.05.2019, 16:11 9
Zeropil, вы слишком идеалистичны в данном вопросе, такого не бывает, всегда приходится жертвовать, и часто для решения простых задач приходится городить подобное в виде IPC каналов или передачи через память как выше описано.
0
16 / 0 / 0
Регистрация: 23.02.2019
Сообщений: 106
03.05.2019, 16:42  [ТС] 10
Цитата Сообщение от freeba Посмотреть сообщение
В таком случае попробуйте IPC Channels,
Как вариант годится, но существует вероятность утечки.

Добавлено через 31 минуту
Цитата Сообщение от SeIZVeIZ Посмотреть сообщение
часто для решения простых задач приходится городить подобное в виде IPC каналов или передачи через память как выше описано.
Не обязательно, не всегда нужен костыль, чтобы получить велосипед. К примеру,
https://www.cyberforum.ru/csha... 42135.html
3.6.1. Marshal.StructureToPtr и Marshal.PtrToStructure
Можно использовать что-то подобное, правда я не знаком с данным классом, и никогда не работал с ним. Потому не знаю как изобрести велосипед на практике.

Знаю, что можно взять указатель на блок памяти и обратиться к нему для чтения данных. И как по мне эта перспектива вполне реализуема.
0
Эксперт .NET
6473 / 4054 / 1600
Регистрация: 09.05.2015
Сообщений: 9,489
03.05.2019, 22:58 11
Используйте вариант, предложенный вам во втором посте. Он самый оптимальный.

Цитата Сообщение от Zeropil Посмотреть сообщение
У меня не гипертексты, мне нужно передать лишь парочку значений типов int и string. И нагружать лишними манипуляциями программу нет смысла. Нужен быстрый и безотказный метод.
Причем тут гипертексты? Где вы нашли лишние манипуляции, которые будут что-то нагружать? MemoryMappedFile скорее всего самый быстрый из возможных методов...

"Сервер"
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
using System;
using System.IO.MemoryMappedFiles;
using System.Text;
 
namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = new Random().Next();
 
            Console.WriteLine($"x={x}");
 
            MemoryMappedFile mmf = MemoryMappedFile.CreateNew("testmmf", 20, MemoryMappedFileAccess.ReadWrite);
            MemoryMappedViewAccessor mmva = mmf.CreateViewAccessor();
 
            mmva.Write<int>(0, ref x);
 
            var strBytes = Encoding.UTF8.GetBytes("test!");
 
            int strLen = strBytes.Length;
 
            mmva.Write<int>(4, ref strLen);
            mmva.WriteArray<byte>(8, strBytes, 0, strBytes.Length);
 
            Console.WriteLine("MemoryMappedFile created!");
 
            Console.ReadKey();
        }
    }
}
"Клиент"
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
using System;
using System.IO.MemoryMappedFiles;
using System.Text;
 
namespace MemMappedIpc
{
    class Program
    {
        static void Main(string[] args)
        {
            MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmmf", MemoryMappedFileRights.ReadWrite);
            MemoryMappedViewAccessor mmva = mmf.CreateViewAccessor();
 
            mmva.Read<int>(0, out int x);
            mmva.Read<int>(4, out int strLen);
            byte[] strBytes = new byte[strLen];
            int read = mmva.ReadArray<byte>(8, strBytes, 0, strBytes.Length);
 
            Console.WriteLine($"x={x}, read={read}, strLen={strLen}, str={Encoding.UTF8.GetString(strBytes)}");
 
            Console.ReadKey();
        }
    }
}
1
16 / 0 / 0
Регистрация: 23.02.2019
Сообщений: 106
05.05.2019, 11:26  [ТС] 12
Цитата Сообщение от Someone007 Посмотреть сообщение
Используйте вариант, предложенный вам во втором посте. Он самый оптимальный.
Спасибо, но я нашел более подходящий способ.

C#
1
2
3
4
5
//Использовать дочерним приложением...
AppDomain.CurrentDomain.SetData("Message", ("guess what... ");
 
//Использовать родительским приложением.
domain.GetData("Message")
Почему именно этот способ?
1) Запуск приложений и так проходит в отдельном домене.
2) Мало кода.
3) Минимум манипуляций.
4) При попытке запуска приложений не в том порядке, возникнет "ошибка"(приложение не получит ответ).
5) Ошибок при выполнении не будет, если запуск будет в строгом порядке.
6) Вторую копию дочернего приложения нельзя будет запустить пока существует домен.
0
Эксперт .NET
6473 / 4054 / 1600
Регистрация: 09.05.2015
Сообщений: 9,489
05.05.2019, 12:01 13
Цитата Сообщение от Zeropil Посмотреть сообщение
но я нашел более подходящий способ
Вы уверены что это работает? Как вы получаете домен другого приложения?

Добавлено через 24 минуты
Возможно вы делаете что-то типа этого?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
 
namespace ConsoleApp5
{
    class Program
    {
        static void Main(string[] args)
        {
            var domain = AppDomain.CreateDomain("test");
 
            domain.SetData("ParentMessage", "Parent Message...");
 
            domain.ExecuteAssembly("someapp.exe");
 
            var msg = domain.GetData("ChildMessage");
 
            Console.WriteLine($"Got message from child: {msg}");
 
            Console.ReadKey();
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
 
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.SetData("ChildMessage", "Child Message...");
 
            var msg = AppDomain.CurrentDomain.GetData("ParentMessage");
 
            Console.WriteLine($"Got message from parent: {msg}");
        }
    }
}
0
16 / 0 / 0
Регистрация: 23.02.2019
Сообщений: 106
05.05.2019, 16:31  [ТС] 14
Цитата Сообщение от Someone007 Посмотреть сообщение
Вы уверены что это работает? Как вы получаете домен другого приложения?
В общей библиотеке 2 функции, одна создает домен и запускает приложение...
К другой функции обращается уже само приложение предоставляя ссылку на домен, в котором выполняется.

C#
1
2
3
4
5
//Вызов из дочернего приложения...
public static void Send(AppDomain domain, obj msg)
{
    domain.SetData("ParentMessage", msg);
}
Т.к. домен присваивается приложению при запуске, то логично, что оно ссылаясь на библиотеку, обращается непосредственно к своему домену.
Единственный недостаток, считывание я провожу с задержкой через 2 сек, после запуска дочернего приложения. Т.к. не существует события, которое сигнализирует о передаче сообщения.
В моем случае это играет роль, т.к. снижает нагрузку на оба приложения.
И, в моем случае передача идет односторонняя от дочернего к родительскому и только. Ведь дочернему приложению можно передать параметры через аргументы запуска.
0
05.05.2019, 16:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.05.2019, 16:31
Помогаю со студенческими работами здесь

Работа с памятью
Добрый день всем. Я только начал изучение C#(раньше работал c: C++ маленько - т.е. общее...

Работа с памятью процесса
Всем привет! Существует чит (трейнер), он изменяет некоторые значения в памяти игры. Я узнал эти...

Работа напрямую с памятью
Такая проблема: есть структура Struct {int a,int b} еще есть две строки требуется скопировать...

AForge и работа с памятью
Добрых времени суток. При использовании AForge для захвата картинки с вебкамеры память начинает...


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

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

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