Wtyczki, wymiana danych między procesami

0

Mam jeden program w C# dla .NET/Mono w Windows Forms.

Chodzi o coś w rodzaju wtyczek do programu, jak to zrealizować?

W programie głównym jest np. przycisk "Uruchom wtyczkę" i wskazuję plik z wtyczką. Sama wtyczka to jest też program w C# w Windows Forms.

Tylko cały figiel polega na nawiązaniu współpracy między programem glównym a wtyczką.

Myślę, że takim "kanałem komunikacyjnym" mógłbyby być pewien zestaw zmiennych lub jedna zmienna "String" lub tablica bajtów "byte[]" o określonej wielkości (reprezentująca pewien obszar RAMu). Istotne jest to, żeby obydwa programy miały dostęp do tych zmiennych. Jeżeli nie zmienne, to "MemoryStream".

Kiedyś realizowałem coś takiego za pomocą pliku tymczasowego na dysku, jednak ta metoda ma pewne wady, dlatego chciałbym zrealizować to samo w obrębie pamięci operacyjnej.

Czy coś takiego da się zrobić? Jeżeli tak, to w jaki sposób?

0

Dziwnie kombinujesz. Lepiej raczej przygotuj interfejs jaki ta wtyczka ma realizowac, a ona niech go zaimplementuje. Po wskazaniu pliku ladujesz assembly do pamieci, szukasz interfejsu i dzialasz na jego metodach, proste. PS. To nie musi byc Windows Forms...

0

A komunikacje miedzy programami lepiej zrealizowac po sieci (serwer na localhoscie)

0

Tutaj raczej nie ma potrzeby, bo ani to osobny program, ani proces. Chyba, ze autor rozumie wtyczke troche inaczej niz sie to zwykle przyjmuje ;)

0
johny_bravo napisał(a)

Dziwnie kombinujesz. Lepiej raczej przygotuj interfejs jaki ta wtyczka ma realizowac, a ona niech go zaimplementuje. Po wskazaniu pliku ladujesz assembly do pamieci, szukasz interfejsu i dzialasz na jego metodach, proste. PS. To nie musi byc Windows Forms...

Czyli w projekcie wtyczki jest na przykład:

interface Kanal
{
 void Wyswietl(string S);
 string Pobierz();
}

class Wtyczka : Kanal
{
 void Wyswietl(string S);
 {
  Label1.Text = S;
 }
 string Pobierz();
 {
  return Textbox1.text;
 }
 // i inne metody i zmienne związane z działaniem samej wtyczki jako programu.
}

I wtyczka jest normalnym plikiem EXE.

A w programie głównym chcę wywoływać metody, które są w interfejsie wtyczki. Elementy Label1 i Textbox1 są elementami wtyczki.

W takim razie, co w programie głównym trzeba doimplementować, żeby to zagrało? Wtedy komunikacja odbywałaby sie przez interfejs "Kanal".

[losowa nazwa] napisał(a)

A komunikacje miedzy programami lepiej zrealizowac po sieci (serwer na localhoscie)

Rozumiem, że program główny to serwer (localhost), a wtyczka to klient (łączy się z "localhost"). Ale czy takie coś ruszy np. na komputerze pozbawionym karty sieciowej?

0
johny_bravo napisał(a)

Tutaj raczej nie ma potrzeby, bo ani to osobny program, ani proces. Chyba, ze autor rozumie wtyczke troche inaczej niz sie to zwykle przyjmuje ;)

Ja rozumiem wtyczke jako osobny program współpracujacy z programem głównym. Tylko, że program główny "zna" tylko sposób wprowadzania i wyciągania danych, cała reszta to jest "czarna skrzynka". Natomiast od strony wtyczki, program główny jest czarną skrzynką, od której tylko otrzymuje dane i wysyła te dane. Docelowo, napisanie kolejnej wtyczki ma być możliwe rówież przy braku dostępu do kodu źródłowego do programu głównego.

To można przyrównać do działania konsoli gier na kadridże. Konsola "nie zna" budowy i działania kadridża, tylko ma złącze "na zewnątrz", przez które przesyła się dane w sposób określony przez projektanta konsoli. Natomiast kadridż to osobny układ elektroniczny, który przetwarza dane własne (naczęściej kadridż zawiera pamięć ROM) oraz dane otrzymane przez złącze i wysyła dane przez złącze. Przy tym przyrównianiu, porgram główny to konsola, a kadridż to wtyczka, a inny kadridż z inną grą to druga wtyczka, jednak obie maja ten sam interfejs.

0

No dobrze, tylko po co utrudniac sobie zycie osobna aplikacja, skoro latwiej zaladowac dllke? Co do wczesniejszych pytan - poczytaj o refleksji (co trzeba doimplementowac, zeby zagralo), drugie - tak, bez sieciowki tez pojdzie, nie jest wymagana.

0

Teraz są poinstalowane domyślnie sterowniki protokołu TCP/IP, loopbacki i inne bajery. Kiedyś na Windowsie 98 bez posiadania karty sieciowej nie można było pograć z botami w Counter-Strike :P.

0

Patrząc na to: http://4programmers.net/Forum/viewtopic.php?id=144168

Udało mi się zrobić test, ale nie do końca to wyszło:

Program główny:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;

namespace MainPrg
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        string PlugFile = "E:\\Csharp\\DLLtest\\DLLtest\\DLLtest\\bin\\Debug\\DLLtest.dll";


        Assembly As;
        Object Ob;
        MethodInfo Mstart;
        MethodInfo Mrec;
        MethodInfo Msnd;

        // Uruchom
        private void button1_Click(object sender, EventArgs e)
        {
            As = Assembly.LoadFile(PlugFile);
            Type[] TT = As.GetTypes();

            foreach (Type Tw in TT)
            {
                // Kanal - nazwa interfejsu
                // TestDll - nazwa klasy implementujacej interfejs "Kanal"
                if (Tw.ToString().IndexOf("Kanal") > (-1))
                {

                    // Tu sie zatrzymuje i blad: "Cannot create an instance of an interface."
                    Ob = Activator.CreateInstance(Tw);  

                    
                    Mstart = Tw.GetMethod("Wystartuj");
                    Mrec = Tw.GetMethod("Pobierz");
                    Msnd = Tw.GetMethod("Wyswietl");
                }
            }
            Mstart.Invoke(Ob, null);
        }

        // Wyslij
        private void button2_Click(object sender, EventArgs e)
        {
            Object[] Params = new Object[1];
            Params[0] = textBox1.Text;
            Msnd.Invoke(Ob, Params);
        }

        // Pobierz
        private void button3_Click(object sender, EventArgs e)
        {
            label1.Text = (string)(Mrec.Invoke(Ob, null));
        }
    }
}

Wtyczka:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace DLLtest
{
    public interface Kanal
    {
        void Wystartuj();
        void Wyswietl(string S);
        string Pobierz();
    }

    public class TestDll : Kanal
    {
        Form1 Frm;

        public void Wyswietl(string S)
        {
            Frm.label1.Text = S;
        }

        public string Pobierz()
        {
            return Frm.textBox1.Text;
        }

        public void Wystartuj()
        {
            Frm = new Form1();
            Frm.Visible = true;
        }
    }
}

Jak w programie głównym w miejscu "if (Tb.ToString().IndexOf("Kanal") > (-1))" wpisze nazwę klasy, to wszystko działa prawidłowo, a jak wpiszę w tym miejscu nazwe interfejsu, to pokazuje się ten bład w miejscu wskazanym w kodzie.

W takim razie, jak wykorzystać interfejs?

0

Normalnie nie da sie stworzyc obiektu po samym interfejsie, no bo jak? skoro nie ma implementacji metod.
Ale mozna trochę nagiąć tę zasadę.

   class InterfProxy : RealProxy
    {
        public InterfProxy(Type type)
            : base(type)
        {
        }
        public override IMessage Invoke(IMessage msg)
        {
            Console.WriteLine("wywolana metoda - "+msg.Properties["__MethodName"]);
            return new ReturnMessage(null,null);
        }
    }

    interface IService
    {
        void LogMe(string name, string hash_password);
    }
             IService proxy = (IService)new InterfProxy(typeof(IService)).GetTransparentProxy();

             proxy.LogMe("michal", "$%%$^%$^%^");
             Console.ReadKey();

Może Ci się przyda, owczywiscie return new ReturnMessage(null,null);
nie moze tak zostać. Trzeba podać jakieś sensowne parametry.

0
johny_bravo napisał(a)

Dziwnie kombinujesz. Lepiej raczej przygotuj interfejs jaki ta wtyczka ma realizowac, a ona niech go zaimplementuje. Po wskazaniu pliku ladujesz assembly do pamieci, szukasz interfejsu i dzialasz na jego metodach, proste. PS. To nie musi byc Windows Forms...

dark_astray napisał(a)

Normalnie nie da sie stworzyc obiektu po samym interfejsie, no bo jak? skoro nie ma implementacji metod.
Ale mozna trochę nagiąć tę zasadę.

Ten kod sprawia wrażenie "okrężnej drogi", więc myślę, że nie warto się nim zajmować, bo nie o to chodzi, żeby "na siłę" tworzyć interfejs, tylko o to, żeby mieć dostęp do programu-wtyczki. Początkowo myślałem, że Johnemu chodziło o interfejs w rozumieniu programowania obiektowego i dlatego próbowałem go wykorzystać. Teraz właśnie mam wątpliwość, czy cy Johnemu chodzi o interfejs w rozumieniu programowania obiektowego, czy chodzi o interfejs w rozumieniu "potocznym", a w rzeczywistości robi się to tak, jak powyżej napisałem, czyli bez interfejsu, tylko bezpośredni dostęp do klasy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1