Konzept für DLL-Aufrufe



  • Tachyon schrieb:

    Wieso lässt Du den Benutzer nichts selbst die Objekte anlegen und benutzen?

    Weil die DLL sprachunabhängig sein muss. Sie soll mindestens aus C, C++, LabVIEW und C# nutzbar sein. Je mehr desto besser.



  • DarthZiu schrieb:

    Weil die DLL sprachunabhängig sein muss.

    Und wieso ist sie so Deiner Meinung nach nicht sprachunabhängig? Das ist ein reines C Interface, welches man praktisch überall einbinden kann.



  • Ich glaube (auch wenn ich es jetzt nicht genau weiß), dass das so unter LabVIEW nicht funktioniert.

    Außerdem kann ich dem User nicht die Klassen zur Verfügung stellen, weil da noch einiges an Datenaustausch und Verwaltung zwischen den Objekte oder mit den Objekten stattfinden wird.

    Eigentlich möchte ich das so lassen, dass der User nur eine Funktion mit dem Namen des Objektes aufrufen kann.

    Nur stört mich halt, dass ich dafür immer diese redundanten Zeilen aufrufen muss.



  • Okay, wenn Du es so lassen willst, ist das Deine Sache. Unter LabView, Matlab, Ada, Java und C# kann man es auf jeden Fall wie von mir gezeigt machen.



  • Welchen Nachteil siehst du bei Tachyons Ansatz?

    Dabei kann es sich naemlich eigentlich nur um ein Missverstaendnis handeln, denn genau so wie er es beschreibt ist der richtige Weg.

    Du verwendest char* zur Identifizierung welches Objekt verwendet werden soll, Tachyon verwendet Adressen. Der Trick dabei ist, du gibst dem Client Code bereits die richtige Adresse. Dem Client ist es ja komplett egal was er bekommt, sei es ein char*, ein void* oder ein int. Er kann so oder so nichts damit anfangen.

    Wenn du nun einen void* hergibst, kannst du zB folgendes machen:

    typedef void* handle;
    
    //C Interface:
    handle create_object();
    destroy_object(handle);
    int tu_was(handle);
    
    //Code in der DLL:
    
    handle create_object() {
      return new klasse();
    }
    
    destroy_object(handle o) {
      klasse* p = static_cast<klasse*>(o);
      delete p;
    }
    
    int tu_was(handle o) {
      //optional: if(!o)return ERROR;
      klasse* p = static_cast<klasse*>(o);
      return p->tu_was;
    }
    
    //Client Code:
    
    handle h = create_object();
    tu_was(h);
    destroy_object(h);
    


  • Mmh, na gut. Ich werd mir das mal anschauen, ob man damit so arbeiten kann.

    Danke für die Hilfe.



  • Hab das jetzt mal ausprobiert, beispielhaft mit LabVIEW. Ist ne coole Methode, die Objekte an den Anwender zu übergeben.

    Nun frage ich mich allerdings, wie das mit der Absturzsicherheit aussieht. Bei der Variante mit den übergebenen Namen prüfe ich, ob ein Objekt existiert und gebe nur grünes Licht, wenn es da ist.
    Mit dem Handle für den Anwender kann ich das ja nicht machen. Wenn der Anwender z.B. das Handle (ich benutze ein int dafür) verändert (z.B. inkrementiert), kann ich das ja in der DLL nicht abfangen. Oder geht das irgendwie, dass ich erkenne, ob das Handle auf ein existierendes Objekt zeigt?



  • Für die Dummheit des Anwenders bist Du aber nicht verantwortlich. Bei Deiner Variante könnte man z.B. die Nullterminierung des Strings weg lassen. Dann knallt es auch und das ist nicht weniger bösartig als das willkürliche inkrementieren eines Pointers...



  • Du kannst theoretisch schon alles abfangen, die Frage ist aber ob es Sinn macht. Du merkst dir einfach alle Adressen und schaust nach ob es die übergebene gibt.

    Aber wozu? Wenn der Anwender einen Absturz provozieren will schafft er es. Dagegen musst du dich nicht schützen, bzw. kannst es garnicht.

    cout prüft ja zB auch nicht ob du ihm Daten gibst die OK sind. Weil der Aufwand den Nutzen nicht rechtfertigt.

    Wenn du komplette Sicherheit willst musst du auf managed Systeme umsteigen, aber auch dort kann man mit etwas Aufwand Anwendungen abstürtzen lassen.



  • Okay, ihr habt mich überzeugt.

    Vielen Dank für den Support.


Anmelden zum Antworten