NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Komunikace mezi procesy C#/C++

V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
rdaek
Člen
Avatar
rdaek:29.10.2017 15:13

Ahoj,
dělám na jedné aplikaci, která se skládá z jádra v C++ a vizualizačních částí v C#. Potřeboval bych vyřešit nějak komunikaci mezi těmito procesy. Po nějakém hlednání jsem našel rozumnou (teda alespoň mi tak přijde) možnost ve formě Pipes.
Je nějaký dobrý tutoriál na používání a implementování Pipes ? ;)
Díky

Odpovědět
29.10.2017 15:13
Důležité je udělat program blbuvzdorným... Je pravda že mi často dost vzdorují :D
Avatar
Odpovídá na rdaek
sadlomaslox25:29.10.2017 15:22

A potrebujes to mit nutne ve dvou procesech ? Ze C# aplikace muzes primo pres pinvoke funkce z C++ a predavat data tam i zpet. Dokonce to jde i naopak ze C++ muzes primo volat C# (bud managed C++ nebo pres DllExport bez mezi projektu).

 
Nahoru Odpovědět
29.10.2017 15:22
Avatar
rdaek
Člen
Avatar
Odpovídá na sadlomaslox25
rdaek:29.10.2017 15:28

jo to vím ;) chtěl jsem to udělat asynchroní, že C++ běží ve smyčce nějaký úkol, a ve chvíli kdy ho dodělá, pošle výsledek pomocí nějaké komunikace.. a C# mezitím dělá něco jiného a když zjistí že má data tak je zpracuje, zareaguje a pak dělá si dále svoje věci ;) ale i tak popřemýšlím nad tím to udělat pomocí volání pInvokem

Nahoru Odpovědět
29.10.2017 15:28
Důležité je udělat program blbuvzdorným... Je pravda že mi často dost vzdorují :D
Avatar
Petr Homola
Tvůrce
Avatar
Odpovídá na rdaek
Petr Homola:29.10.2017 15:33

Nejlepší je udělat knihovnu .NET v C++/CLI a tu pak volat ze C#. Knihovnu i hlavní aplikaci lze mít v jednom “solution” ve Visual Studiu. Typicky půjde jen o jednoduchý wrapper. Překladač umí pro C++ generovat čistě řízený kód včetně věcí z STL (do C++14, pro C++17 už se musí překládat nativně).

 
Nahoru Odpovědět
29.10.2017 15:33
Avatar
Martin Dráb
Tvůrce
Avatar
Odpovídá na rdaek
Martin Dráb:29.10.2017 15:33

Případně můžeš použít sockety. A pokud ti nevadí to řešit hodně na manuální úrovni, tak přes sdílenou paměť.

Co se týče rour (pipes), budeš asi potřebovat ty pojmenované, protože komunikuješ mezi dvěma procesy a oba musí získat přístup ke stejným rourám (druhá možnost je, že tvoje vizualizační část spustí to jádro, a pak mu může předat odkazy na ty roury přímo). Nevím, jak je toto dobře zapouzdřeno v C#, ale v C/C++ za použití Windows API mi roury (ty pojmenované) přišly celkem netriviální. Jednodušší bylo použít sockety.

Nahoru Odpovědět
29.10.2017 15:33
2 + 2 = 5 for extremely large values of 2
Avatar
Petr Homola
Tvůrce
Avatar
Odpovídá na rdaek
Petr Homola:29.10.2017 15:34

P/Invoke není moc dobrý nápad, takovéto věci se řeší pomocí C++/CLI.

 
Nahoru Odpovědět
29.10.2017 15:34
Avatar
Martin Dráb
Tvůrce
Avatar
Odpovídá na Petr Homola
Martin Dráb:29.10.2017 15:50

C++/CLI

Z mojí zkušenosti: better to avoid that at all costs :-).

Pokud si uděláš vhodné rozhraní, které vystačí s předáváním primitivních typů, tak se C++/CLI dá vyhnout.

Nahoru Odpovědět
29.10.2017 15:50
2 + 2 = 5 for extremely large values of 2
Avatar
Petr Homola
Tvůrce
Avatar
Odpovídá na Martin Dráb
Petr Homola:29.10.2017 15:53

Dá se tomu vyhnout, ale není k tomu důvod, P/Invoke je pomalejší a nezaručuje typovou bezpečnost.

 
Nahoru Odpovědět
29.10.2017 15:53
Avatar
Martin Dráb
Tvůrce
Avatar
Odpovídá na Petr Homola
Martin Dráb:29.10.2017 16:11

Myslíš jako psát celý projekt (nebo alespoň tu vizualizační část) v C++/CLI, ne jen ten překlad mezi C# a C++? To pak ano. Osobně bych do toho ale nešel. Mám zkušenost s projektem, kde jsme C++/CLI používali právě pro překlad volání mezi C# a C++ a bylo to dost šílené (naštěstí se pak ukázalo, že .NET nemůžeme moc dobře použít, takže jsme se zbavili i CLI)..

V pomalosti pinvoke bych problém neviděl (v release režimu by ta cena neměla být moc vysoká). Předpokládám, že oproti času, který na jedno volání do jádra toto jádro stráví výpočty, bude takový, že cena samotného volání bude zanedbatelná.

Nahoru Odpovědět
29.10.2017 16:11
2 + 2 = 5 for extremely large values of 2
Avatar
rdaek
Člen
Avatar
rdaek:29.10.2017 16:21

Fajn :D děkuji za rady bohužel nejsem o moc moudřejší než na začátku ;) nastíním situaci trochu více. C++ ve spojení s OpenCV(pouze na grabbing framu z kamery, zpracování už musím psát sám) se stará o zpracování obrazu z kamery. Během toho běží vizualizace v C#, která zobrazuje informace na obrazovce, různá nastavení apod. Ve chvíli, kdy C++ detekuje žádaný objekt - tedy ne každý průběh vyhledávacího algoritmu - pošle informace o objektu (data se mohou měnit na základě typu objektu) a C# si je převezme a zahrne do informací atd.
Aktuálně to asi budu řešit dvěma vlákny C# běžícími nezávisle na sobě, kde jedno řeší vizualizace a druhé ve smyčce volá knihovnu v C++ pomocí [DllImport], což by měl být pInvoke, pokud to dobře chápu. Trochu v tom tápu, dělám tohle poprvé ;) Mohl by tento myšlenkový pochod být OK? Nebo je lepší použít jiné řešení?

Nahoru Odpovědět
29.10.2017 16:21
Důležité je udělat program blbuvzdorným... Je pravda že mi často dost vzdorují :D
Avatar
Petr Homola
Tvůrce
Avatar
Petr Homola:29.10.2017 16:22

Co na tom bylo šíleného? C++/CLI se typicky používá jen pro wrapper, když je k dispozici zdroják, není co řešit, jinak se dá volat přímo nativní DLL bez P/Invoke a pak se použije IJW/C++ Interop pro provázání s C#. Docela by mě zajímalo, v čem by měl být problém, já nikdy na žádný nenarazil (krom toho, že to jede jen na Windows).

 
Nahoru Odpovědět
29.10.2017 16:22
Avatar
Petr Homola
Tvůrce
Avatar
Odpovídá na rdaek
Petr Homola:29.10.2017 16:29

Je ten kód v C++ k dispozici jako zdroják, nebo je to jen nativní DLL? V prvním případě to chce přeložit v pure režimu. Ve druhém se holt bude muset udělat nativní wrapper. Asynchronní komunikace jde efektivně přes producer/subscri­ber. Nebo pollingem, ale to už není tak "hezké" řešení.

 
Nahoru Odpovědět
29.10.2017 16:29
Avatar
rdaek
Člen
Avatar
Odpovídá na Petr Homola
rdaek:29.10.2017 16:46

C++ dělám já, takže dostupný jako zdroják a ze C# volám takhle:
(je to pouze testovací implementace zda to vůbec funguje)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using CameraCore;
namespace CameraWrapper
{


    class Program
    {
        [DllImport("CameraCore.dll")]
        public static extern int Secti(int a, int b);

        static void Main(string[] args)
        {
            try
            {
                test t = new test();
                while (true)
                {
                    Console.WriteLine(t.Secti(5, 4));
                    Console.ReadKey();
                }
            }
            catch (Exception E) { Console.WriteLine(E.Message); }
        }
    }
}
Editováno 29.10.2017 16:47
Nahoru Odpovědět
29.10.2017 16:46
Důležité je udělat program blbuvzdorným... Je pravda že mi často dost vzdorují :D
Avatar
Petr Homola
Tvůrce
Avatar
Odpovídá na rdaek
Petr Homola:29.10.2017 16:58

Super, tak teď udělat “public ref class” v C++/CLI a máš to.

 
Nahoru Odpovědět
29.10.2017 16:58
Avatar
rdaek
Člen
Avatar
rdaek:29.10.2017 17:22

pokud je to tohle (jenom hlavička) tak je to super :D
Můžu v class test mít privátní proměnnou, která mi bude držet otevřenou instanci kamery? Přece jen je otevírání streamu při každém volání pomalé a první snímek je vždy černý... Jenom jestli se public ref class chová jako normální třída ;)

using namespace std;
using namespace System;

namespace CameraCore {

        public ref class test
        {
        public:
                int Secti(int a, int b);
        };
}
Nahoru Odpovědět
29.10.2017 17:22
Důležité je udělat program blbuvzdorným... Je pravda že mi často dost vzdorují :D
Avatar
Petr Homola
Tvůrce
Avatar
Odpovídá na rdaek
Petr Homola:29.10.2017 17:33

V ref class lze mít ukazatel na nativní třídu, takže ano, není problém. Chová se trochu jinak, protože ji ruší GC, ale jinak se dá míchat s kódem v C++ bez omezení (až na to C++17).

 
Nahoru Odpovědět
29.10.2017 17:33
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 16 zpráv z 16.