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.
Člen
Zobrazeno 16 zpráv z 16.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
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).
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
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ě).
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.
P/Invoke není moc dobrý nápad, takovéto věci se řeší pomocí C++/CLI.
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.
Dá se tomu vyhnout, ale není k tomu důvod, P/Invoke je pomalejší a nezaručuje typovou bezpečnost.
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á.
Fajn 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í?
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).
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/subscriber. Nebo pollingem, ale to už není tak "hezké" řešení.
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); }
}
}
}
Super, tak teď udělat “public ref class” v C++/CLI a máš to.
pokud je to tohle (jenom hlavička) tak je to super
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);
};
}
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).
Zobrazeno 16 zpráv z 16.