API für eigenes Programm

  • VB.NET

Es gibt 92 Antworten in diesem Thema. Der letzte Beitrag () ist von singu.

    Wie immer laufen Diskussionen mit Dir darauf hinaus, dass Du nicht einmal versuchst Erklärungen zu verstehen: Du gehst immer davon aus man hätte Dich missverstanden und wiederholst Dein Problem im gleichen Wortlaut nochmal .. und nochmal .. und im Zweifelsfall einfach nochmal ?(

    Also jetzt noch einmal von der Pike auf die Grundlagen:

    singu schrieb:

    Also nochmal das Hauptprogramme habe ich in VB.NET geschrieben, das ist ein ausführbares Programm

    Was ist ein "ausführbares Programm" ? In .NET ist das nicht wie in C oder C++ eine Reihe von Assemblercodes , sondern eine DLL (Assembly) die der Compiler mit einem winzigen Startprogramm (Stub) versehen hat und dann die Endung ".exe" gegeben hat. Also wenn Du ein Programm test geschrieben hast, mit FORM1 als Startform, dann ist FORM1 eine Klasse die der Compiler mit dem Stub startet.

    Wir nehmen jetzt ein simples Programm:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Public Sub Hello()
    3. MsgBox("Hello World")
    4. End Sub
    5. Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
    6. Hello()
    7. End Sub
    8. End Class

    Die API der Klasse Form1 besteht jetzt nur aus 1 Methode "Hello". Du kannst sie ausführen , und in dem Bin\Debug Ordner steht test.exe

    Jetzt gehen wir in die Projekteigenschaften und verändern unter Projekteigenschaften->Anwendung den Anwendungstyp auf Klassenbibliothek. Pojektmappe neu erstellen und schwupps steht im Ordner Bin\Debug Ordner test.dll.

    Die kannst Du jetzt in einem anderen Programm per Referenz einbinden, instanziieren und hast Zugriff auf Form1.Hello als Methode.

    War das jetzt verständlich genug ????
    Sorry aber du verstehst es wohl immer noch nicht.

    Das Hauptprogramm wird und darf keine dll werden. Ich möchte eine extra dll haben, die man in andere programme einbinden kann. und mit dieser dll kamm na dann auf ereignisse vom hauptprogramm reagieren und auch funktionen aufrufen, die wiederrum das hauptprogramm drauf reagiert.
    Vielleicht fehlt ihm noch der letzte Schubs:

    Nach den Ausführungen des sehr geschätzten Kollegen ergibt sich natürlich auch eine Schlußfolgerung:

    Theoretisch kannst Du in einem Projekt alle Funktionalitäten (alle Klassen, Eigenschaften, Methoden, Beutelratten und was weiß ich nicht noch alles) definieren die Du für den kompletten Ablauf des Programms brauchst und dann im Nachhinein die Teile die Du eventuell in Form einer API anderen zur Verfügung stellen möchtest in ein anderes Projekt ziehen und aus dem einen eine exe machen und aus der API eine dll (mußt nur die Imports noch anpassen, damit er das Zeug auch findet).

    Also noch einmal langsam zum Mitschreiben: Du machst es so, als wäre alles in einem Projekt, gleichgültig ob API oder nicht.

    Jetzt wird sich bei Dir wahrscheinlich schon ein wenig ein ungutes Gefühl einstellen: "wenn ich das so mache, dann ist das doch alles sehr an nur dieses Programm angepasst und die anderen können mit der dll als API nicht viel anfangen, wenn ich ständig von der API aus auf fix verdrahtete Sachen zugreife."

    Deswegen macht man es z.B. meistens so:

    Nehmen wir an, ich habe ein Hauptprogramm mit Property Arm™ und der Methode werfen()℠. Zudem habe ich in meiner API bzw. dll die Property Bein™ und die Methode treten()℠. Nun möchte ich auf die Property Bein und die Methode treten() zugreifen, kein Thema, sind Public, weil ist ne API und dann sollte das schon offen sein, wenn es vorgesehen ist, dass andere darauf zugreifen.

    Was ist jetzt, wenn ich im Zuge der Arbeiten in der API auf Arm und Methode werfen() zugreifen möchte? Ganz einfach: die Property Arm lasse ich vorher irgendwie das Hauptprogramm übergeben, immerhin will das ja was von mir. Und wenn ich mir das Ganze als Referenz speichere, interessiert es mich auch nicht, wenn sich der Wert mittendrin geändert hat, weil ich mir nur den Speicherbereich ansehe, nicht den Wert der irgendwann mal drin gestanden hat.
    Wie schaut es aus mit der Methode? Also generell sollte man sowas eh nicht machen, eine API ist dazu da um Funktionalitäten zur Verfügung zu stellen und nicht um Funktionalitäten in meinem Hauptprogramm auszuführen. Aber wenn ich das unbedingt brauche, dann kann ich in in meiner API einen Delegaten definieren und mir eben auch da eine Referenz zu einer Methode holen. Und die kann ich dann lustig wie ich bin aufrufen. Mein Hauptprogramm muss mir nur dafür per AddressOf mitteilen wo die Methode ist. Zu trocken? Beispiel:

    Hier meine API-Klasse:

    VB.NET-Quellcode

    1. Public Class MeineAPIKlasse
    2. Public Delegate Sub werfen()
    3. Public werfenAufruf As werfen
    4. Public ReadOnly Property Bein() As String
    5. Get
    6. Return "Bein"
    7. End Get
    8. End Property
    9. Public Sub treten()
    10. Console.WriteLine("Und Tritt...")
    11. End Sub
    12. Public Sub SetWerfen(ByVal werfen As werfen)
    13. Me.werfenAufruf = werfen
    14. End Sub
    15. Public Sub MachMalWerfen()
    16. werfenAufruf.Invoke()
    17. End Sub
    18. End Class


    Und hier meine Hauptanwendung:

    VB.NET-Quellcode

    1. Imports MeineAPI
    2. Module MeineHauptanwendung
    3. Dim mArm As String = "Arm"
    4. Public ReadOnly Property Arm() As String
    5. Get
    6. Return mArm
    7. End Get
    8. End Property
    9. Public Sub werfen()
    10. Console.WriteLine("Und Wurf...")
    11. End Sub
    12. Sub Main()
    13. Console.WriteLine(Arm)
    14. werfen()
    15. Dim MeineAPIKlasse As New MeineAPIKlasse
    16. Console.WriteLine(MeineAPIKlasse.Bein)
    17. MeineAPIKlasse.treten()
    18. MeineAPIKlasse.SetWerfen(AddressOf werfen)
    19. Console.Write("Hier kommt jetzt der Fremdaufruf über die API: ")
    20. MeineAPIKlasse.MachMalWerfen()
    21. Console.ReadKey()
    22. End Sub
    23. End Module


    Also ich schubse das Aufrufen meiner Funktion in der Hauptanwendung über die API-Methode nur an.

    So, ich habe lange überlegt ob ich Dir überhaupt noch helfen soll, ich hab mir jetzt mal ein bißchen Mühe gegeben es auch für Dich verständlich zu machen, ich hoffe, es ist mir geglückt. Und alle Probleme mit Events und so laufen haargenauso ab. Delegat der den Stub (Prozedurkopf) vorgibt und die Adresse über AddressOf rausfinden und übergeben. Der Rest dürfte für Dich >3.000-Beiträge-Profi wohl kein Problem mehr sein.

    Gruß FatFire

    PS: Krieg ich jetzt das Bundesverdienstkreuz, Mami?

    singu schrieb:

    Das Hauptprogramm wird und darf keine dll werden. Ich möchte eine extra dll haben, die man in andere programme einbinden kann. und mit dieser dll kamm na dann auf ereignisse vom hauptprogramm reagieren und auch funktionen aufrufen, die wiederrum das hauptprogramm drauf reagiert.

    Sorry , aber lerne doch bitte erst einmal a) die korrekte Fachsprache und b) Deine Probleme übersichtlich zu strukturieren und zu vermitteln, dann bin ich eventuell auch bereit mir Deine Posts wieder anzuschauen. Ein Duden + Kurs in Rechtschreibung wäre auch keine Fehlinvestition.

    Von einem "Guru" mit 3.441 Beiträgen (Fragen) und Webdesigner kann man das wohl erwarten.
    Wie wärs wenn die dll dein Programm sucht, wenn sie gestartet wird. Dann sendet sie per SendMessage() Ihr eigenes Handle an dein Hauptprogramm. Das fängt dann die Nachricht in der WndProc ab und reagiert darauf. So haben beide das Handle des anderen und können per SendMessage alles mögliche schicken und in der Nachrichtenschleife empfangen und dann die Nachricht bearbeiten
    @singu: du kannst nicht an API schicken...API ist eine bestimmte Funktion aud der Klasse die bestimmtes wert zurück gibt. Du schreibst in deine DLL was du brauchst und per Verweise kannst in dein Programm eibinden oder Dynamisch laden.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „SystemUnknow“ ()

    Nibel schrieb:

    Wie wärs wenn die dll dein Programm sucht, wenn sie gestartet wird. Dann sendet sie per SendMessage() Ihr eigenes Handle an dein Hauptprogramm. Das fängt dann die Nachricht in der WndProc ab und reagiert darauf. So haben beide das Handle des anderen und können per SendMessage alles mögliche schicken und in der Nachrichtenschleife empfangen und dann die Nachricht bearbeiten

    Endlich hat es mal jemand mitbekommen, was ich genau haben will. Die API ist in einem anderen Programm eingebunden, dieses wird ausgeführt, die API ruft nun das Mutterprogramm auf, also das Programm von dem die API stammt und holt sich die Infos. Nun wird im Hauptprogramm ein Event ausgelöst, das für die API bestimmt ist, wie kann ich nun auf dieses Event reagieren. Und an diesem Punkt scheitere ich
    Also das abfangen müsste so gehen:

    VB.NET-Quellcode

    1. 'In der dll
    2. Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Object, ByVal lParam As Object) As Long
    3. Public Sub New()
    4. Dim p() As Process = Process.GetProcessesByName("VBTests")
    5. SendMessage(p(0).Handle, 12345, "Hallo", 0)
    6. End Sub

    VB.NET-Quellcode

    1. 'Im MainProgramm
    2. Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    3. MyBase.WndProc(m)
    4. If m.Msg = 12345 Then
    5. MessageBox.Show(m.WParam)
    6. End If
    7. End Sub
    Hallo zusammen,

    also hier liegt eindeutig ein Kommunikationsproblem vor.

    Singu, du solltest konkret ein Beispiel posten was du eingeltich vor hast, am besten mit einem Beispiel, einem Beispiel dem man auch etwas entnehmen kann, sonst kann dir keiner helfen.

    Desweiteren sagst du ständig, dass du Objektorientiert Programmierst, hmm was heißt bei dir denn Objektorientiert? Nur weil man viele klassen hat programmiert man noch lange nicht objektorientiert, poste doch einfach mal eine methode von dir..

    Eine API zu schreiben ist alles adnere als eine einfache Aufgabe, deswegen sollte man dort schon bescheid wissen, vorallem was überhaupt eine API ist. Denn eine API ist nichts anderes als eine Model Klasse die "simple" Funktionen implementiert. APIs reagieren nicht auf Ereignisse aus dem Hauptprogramm, sondern genau umgekehrt.

    Ich denke du bist deutlich überfordert mit dieser Aufgabe und solltest erstmal ein paar leichtere Übungen machen. Denn dir wurden in diesem Thread schon mehrere Ansätze gezeigt von denen du soziemlich nichts verstanden hast...

    Nibel schrieb:

    Also das abfangen müsste so gehen:

    VB.NET-Quellcode

    1. 'In der dll
    2. Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Object, ByVal lParam As Object) As Long
    3. Public Sub New()
    4. Dim p() As Process = Process.GetProcessesByName("VBTests")
    5. SendMessage(p(0).Handle, 12345, "Hallo", 0)
    6. End Sub

    VB.NET-Quellcode

    1. 'Im MainProgramm
    2. Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    3. MyBase.WndProc(m)
    4. If m.Msg = 12345 Then
    5. MessageBox.Show(m.WParam)
    6. End If
    7. End Sub

    Ich hab das jetzt mal ausprobiert, aber es kommt keine Meldung und auch kein fehler
    @all:

    Ereignisse funktionieren nicht über Prozessgrenzen hinweg. Man kann zwar ein Ereignis als Reaktion auf einen Aufruf an das eigene API feuern, da der Threadkontext in diesem Fall noch passt. Es ist jedoch nicht möglich, in der Hauptanwendung einfach ein Ereignis auszulösen, das dann im Client ankommt. Es funktioniert auch nicht, wenn die Delegaten selbst verwaltet werden und die Liste als Shared deklariert ist. Grund: Der Client registriert eine Methode beim Server. Dazu verwendet er seinen Hauptthread. Der Server reserviert Ressourcen für das Ereignis und gibt keinen Fehler zurück. Ruft der Client nun eine Serverfunktion auf, die das registrierte Event feuert, kommt das Ereignis an. Will nun der Server von sich aus dasselbe Event feuern, muss er zwangsläufig seinen eigenen Hauptthread verwenden, welcher aber von der Registratur nichts mitbekommen hat. Für ihn ist die Delegatenliste leer - das Ereignis kommt beim Client nicht an. Das Problem sind also getrennte virtuelle Speicherbereiche, die alle Prozesse gegeneinander abschotten.

    Ereignisse müssen demnach über eine gemeinsame Instanz (das System) ausgetauscht werden, z.B. durch Remoting mit einem IPC-Channel. Ein beispiel dazu wäre recht komplex, deshalb verzichte ich hier darauf. Die Kurzfassung ist, dass ein gemeinsamer Speicherblock (lokal) oder eine Verbindung anderer Art (remote) eingerichtet wird und das Ereignis inkl. Daten serialisiert übertragen wird.
    Gruß
    hal2000
    @singu
    Kannst du noch einmal beschreiben was du erreichen möchtest. Das ist mir nämlich immer noch unklar. Zuerst habe ich, wie wahrscheinlich alle anderen auch, eine Art Pluginsystem angenommen, doch da du FatFires richtigen Vorschläge vehement ablehnst, ist ein solches nicht dein Ziel. Möchtest du vielleicht eine Schnittstelle zur Kommunikation eines unabhängigem Programm mit deinem "Hauptprogramm" realisieren?

    Kannst du mir bitte deinen letzten Post erläutern? Wie willst du mit einer API kommunizieren? Eine API ist der definierte Weg bzw. die Art und Weise der Kommunikation.

    beate schrieb:

    @singu
    Kannst du noch einmal beschreiben was du erreichen möchtest. Das ist mir nämlich immer noch unklar. Zuerst habe ich, wie wahrscheinlich alle anderen auch, eine Art Pluginsystem angenommen, doch da du FatFires richtigen Vorschläge vehement ablehnst, ist ein solches nicht dein Ziel. Möchtest du vielleicht eine Schnittstelle zur Kommunikation eines unabhängigem Programm mit deinem "Hauptprogramm" realisieren?

    Kannst du mir bitte deinen letzten Post erläutern? Wie willst du mit einer API kommunizieren? Eine API ist der definierte Weg bzw. die Art und Weise der Kommunikation.


    Siehe folgendes Zitat:

    singu schrieb:

    Wie der Titel schon sagt, möchte ich eine API für ein eigenes Programm erstellen. Diese soll Events vom Programm bekommen können, aber die API sollte auch Funktionen und Events feuern können, auf die dann das Hauptprogramm reagiert. Nun such ich nach Anleitungen, die beschreiben wie man sowas macht. Mit Google habe ich nichts gefunden, was mir weiterhilft.


    Ich möchte ganz einfach eine API für ein programm von mir schreiben. Das Programm feuert nach außen hin Events, die die API dann mitbekommt und irgendwas macht.
    Bitte gebrauche nicht mehr den Begriff API sondern benutze Schnittstelle. Vielleicht wird dir dann auch deutlich, dass es schwachsinnig ist zu schreiben, eine Schnittstelle/API feuert Ereignisse.
    Eine API/Schnittstelle definiert einheitliche Methoden die verschiedene Klassen implementieren. Wenn man sich das vor Augen führt sucht man nach einem äquivalent in der Programmiersprache und wird bei Interfaces fündig. Nun schreibt man eines das den eigenen Anforderungen gerecht wird und lässt dies die zu ladenden Klassen implementieren. Anschließend erstellt man einen Plugin loader, der gewünschte DLL's lädt und sie nach Klassen durchsucht die das geschriebene Interface implementieren. Diese Klassen instanziert man und kann sie nun benutzen.
    ich möchte auch kein Plugin-System schreiben. Ich habe ein Programm, für dieses Programm möchte ich eine DLL schreiben, diese DLL kann dann in anderen Programmen mitverwendet werden. Nun wird in dem Programm ein Events ausgelöst, was für die API bestimmt ist, nun soll die DLL dieses Event bekommen und dann ein bestimmten Teil machen. Und das Programm sollte auch reagieren wenn die DLL was macht.