[VC++] C# Internal in C++... habs immer noch nicht verstanden

  • Hallo zusammen,

    eine Frage, die mir die Internetsuche nicht einleuchtend erklären konnte.

    Wie setzt man C# "internal" in C++ um?

    Ich verbessere momentan die Datenkapselung eines meiner Projekte und wollte nicht mehr allzu viele Klassen als public in die DLL exportieren, weil diese Klassen nur aus anderen Klassen innerhalb der DLL genutzt werden sollen - nicht von externen Programmen. Folgendes Beispiel mit Wunsch-Zugriffsoperatoren:

    Code
    Public Application
    
    
    Internal AudioManager
        Internal GetAdapterCount()
        Private GetAdapterCountCallback()

    Erläuterung der Klassen / Methoden und ihrer Aufgaben:
    Application: Diese Hauptklasse ist die einzige wirkliche public-Klasse. Von ihr wird in externen Programmen eine Instanz erzeugt.
    AudioManager: Diese Klasse soll nur "innerhalb" der DLL sichtbar sein. Eine Instanz hiervon erstellt nämlich die Application-Klasse. Von außen sollen aber keine Instanzen erzeugbar sein, weder die Klasse überhaupt sichtbar.
    GetAdapterCount(): Eine Methode, die von Application benötigt wird, um herauszufinden, wieviele Audio-Geräte im Rechner vorhanden sind.
    GetAdapterCountCallback(): Eine Methode, die privat innerhalb des Audio-Managers aufgerufen wird. Für Application oder gar externe Anwendungen soll sie nicht sichtbar sein.

    Ich hoffe, ich konnte so ein wenig erklären, was ich vorhabe: Klassen, die eben nur innerhalb der DLL sichtbar sind und nicht nach außen hin.

    Wie kann ich sowas am besten machen? Momentan habe ich alle Methoden der AudioManager-Klasse private deklariert und dann Application als Friend-Class erwähnt. Allerdings hätte Application dann immer noch Zugriff auf GetAdapterCountCallback(). Und der AudioManager wäre nach außen hin sichtbar.

  • Solange das im gleichen Namespace stattfindet, ist internal so ziemlich das gleiche wie private: Difference between internal and private
    Du darfst nur keine Klasse innerhalb einer anderen deklarieren.

    Zitat von http://msdn.microsoft.com/de-de/library/ba0a1yw2%28v=vs.80%29.aspx


    internal:
    Der Zugriff ist auf die aktuelle Assembly begrenzt.

    private:
    Der Zugriff ist auf den enthaltenden Typ begrenzt.


    Wenn die Assembly bzw. der Hauptnamespace gleichzeitig der enthaltende Typ ist, gibts keinen Unterschied

    Spoiler anzeigen


    Haupt-Laptop:
    Dell Vostro 3560 - i7-3632QM, 6GB
    Rechenknechte:
    Lenovo - i5, 4GB
    Medion - Pentium Dual Core, 3GB
    IBM T60 - Core Duo, 2GB
    Lenovo T400 - Core2Duo, 2GB
    Server:
    Sony - Pentium M, 512MB
    Unbenutzt:
    Noname - Celeron D, 1GB

    Einmal editiert, zuletzt von niwax (8. Juli 2011 um 20:55)

  • Wenn ich Pac-Man richtig verstehe, weiss er was internal tut, viel mehr will er das entsprechende Äquivalent in C++.

    Ich habe wenig Ahnung von .NET Assembly und wenig von C++, aber so wie es scheint, verwendet selbst VC++ für C++-Binärdateien ein anderes System, ist ja letztendlich auch kein .NET Bytecode es gibt in C++ also gar keine direkte Möglichkeit, die Sichtbarkeit eines Symbols einzuschränken - du musst mit Headerfiles und dem Linker arbeiten. Aber keine Ahnung wie das bei MSVC++ geht.

    C# internal == public C++?
    C#: Can i write “private:” or “protected:” regions like in C++?

    Wobei ich keinen Grund sehe, warum man das unbedingt will. Falls jemand nen Unsinn mit dem Binärcode anstellen will, hält ihn auch "Internal" nicht davon ab.

  • Zitat von gandro


    Wobei ich keinen Grund sehe, warum man das unbedingt will. Falls jemand nen Unsinn mit dem Binärcode anstellen will, hält ihn auch "Internal" nicht davon ab.


    Es ist aber sauberer, dem User die Funktionen zu geben, die er gebrauchen kann/soll als alles offenzulegen.

    Spoiler anzeigen


    Haupt-Laptop:
    Dell Vostro 3560 - i7-3632QM, 6GB
    Rechenknechte:
    Lenovo - i5, 4GB
    Medion - Pentium Dual Core, 3GB
    IBM T60 - Core Duo, 2GB
    Lenovo T400 - Core2Duo, 2GB
    Server:
    Sony - Pentium M, 512MB
    Unbenutzt:
    Noname - Celeron D, 1GB

  • Zitat von gandro


    Dafür gibts API-Dokumentation.


    Und die offenen Funktionen stimmen im Optimalfall mit der Dokumentation überein.

    Spoiler anzeigen


    Haupt-Laptop:
    Dell Vostro 3560 - i7-3632QM, 6GB
    Rechenknechte:
    Lenovo - i5, 4GB
    Medion - Pentium Dual Core, 3GB
    IBM T60 - Core Duo, 2GB
    Lenovo T400 - Core2Duo, 2GB
    Server:
    Sony - Pentium M, 512MB
    Unbenutzt:
    Noname - Celeron D, 1GB

  • Das Problem ist nur, dass die Methoden, die ich intern in verschiedenen Klassen verwende, nicht für Dritte sichtbar sein sollen... naja, ich denke, ich nehme da das etwas Spaghetticode-wirkende friend class-Konzept :/
    Prio. A ist bei diesem Projekt nämlich, dass der Nutzer der DLL wirklich nur das sieht, um jetzt z.B. einen Sound abzuspielen, und nicht Hilfsmethoden etc., die intern verwendet werden.

  • Hatte ich im Eingangspost eigentlich erwähnt. Innerhalb der DLL sollen bestimmte Methoden von unterschiedlichen Klassen sichtbar sein, aber außerhalb der DLL, also in externen Programmen die die DLL nur nutzen, sollen sie nicht sichtbar sein.

  • Oder du verlagerst alle in der Dll sichtbaren Funktionen in eine DLL-Private Klasse.

    Spoiler anzeigen


    Haupt-Laptop:
    Dell Vostro 3560 - i7-3632QM, 6GB
    Rechenknechte:
    Lenovo - i5, 4GB
    Medion - Pentium Dual Core, 3GB
    IBM T60 - Core Duo, 2GB
    Lenovo T400 - Core2Duo, 2GB
    Server:
    Sony - Pentium M, 512MB
    Unbenutzt:
    Noname - Celeron D, 1GB

  • Dann würde ich aber die OO ad absurdum führen, wenn ich Audio-spezifische und Video-spezifische Funktionen einfach in eine einzelne private Klasse verschiebe.

  • Wieso denn? Eine private Klasse AudioTools und eine VideoTools wäre doch sogar eher OO als die Funktionen für die Dll sichtbar zu machen, aber für andere nicht und so zwei unterschiedliche Typen zu produzieren.

    Spoiler anzeigen


    Haupt-Laptop:
    Dell Vostro 3560 - i7-3632QM, 6GB
    Rechenknechte:
    Lenovo - i5, 4GB
    Medion - Pentium Dual Core, 3GB
    IBM T60 - Core Duo, 2GB
    Lenovo T400 - Core2Duo, 2GB
    Server:
    Sony - Pentium M, 512MB
    Unbenutzt:
    Noname - Celeron D, 1GB

  • Zitat von Pac-Man

    Prio. A ist bei diesem Projekt nämlich, dass der Nutzer der DLL wirklich nur das sieht, um jetzt z.B. einen Sound abzuspielen, und nicht Hilfsmethoden etc., die intern verwendet werden.


    Wird den Benutzer nicht davon abhalten, die Hilfsmethoden trotzdem zu verwenden, falls er das will.

    Ich hab wie gesagt so gut wie keine Ahnung von MSVC, aber nach bisschen googeln sind mir noch folgende Dinge eingefallen:

    1. Warum machst du nicht einfach für jede Klasse (z.B. Application) eine erbende Klasse ApplicationAPI, wo du alle public Methoden drin hast, während alle geheimen protected Methoden in der Vaterklasse Application drin sind - und ApplicationAPI wird dann in die DLL exportiert.

    2. Wie entscheidet der Compiler überhaupt, welche Symbole in die DLL exportiert werden, und welche nicht? Es gibt ja offenbar eine Export-Anweisung, kannst du nicht einfach standradmässig alle Symbole versteckt halten und nur die exportieren, die du willst?

  • Zitat von gandro

    1. Warum machst du nicht einfach für jede Klasse (z.B. Application) eine erbende Klasse ApplicationAPI, wo du alle public Methoden drin hast, während alle geheimen protected Methoden in der Vaterklasse Application drin sind - und ApplicationAPI wird dann in die DLL exportiert.


    Das klingt noch am besten.

    Ich dachte nur, ähnliches ginge auch ohne Verschieben von Methoden in andere Klassen, denn das Projekt an sich ist fertig, und jetzt alles rumzuschieben ist unpraktisch.
    Irgendwas wie "public private:" (ja, so einen nicht funktionierenden Firlefanz spuckte bei meinen Suchen die Internetsuche teilweise aus) solle es es angeblich geben. Konnte ich nicht nutzen. Vermutlich nutzen die Personen, die das gepostet haben, einen Homebrew-Compiler... :S

    Zitat von gandro

    2. Wie entscheidet der Compiler überhaupt, welche Symbole in die DLL exportiert werden, und welche nicht? Es gibt ja offenbar eine Export-Anweisung, kannst du nicht einfach standradmässig alle Symbole versteckt halten und nur die exportieren, die du willst?


    Soweit ich damit herumexperimentiert habe, hat der Compiler sofort rumgezickt, wenn eine exportierte Klasse eine nicht-exportierte Klasse nutzt. Von daher konnte ich durch Nicht-Export die Klasse nicht nach außen hin verstecken, weil ich sie exportieren musste.

    Naja, also momentan bin ich ganz zufrieden mit dem Spaghetti-Friend-Classes. Ist zwar suboptimal, aber bezüglich des Aufwands gegenüber anderen auch von euch vorgeschlagenen Möglichkeiten (mit letztlich vermutlich saubererem Ergebnis) absolut aktzeptabel.
    Es ist ja auch Copyright/Datenschutz/WasAuchImmer-mäßig nicht wichtig, ob der Nutzer nicht doch irgendwie an die von mir zu verstecken-versuchten Klassen rankommt. Es ist nur, dass ich den Nutzer nicht durch IntelliSense oder rumprobieren mit hundert Klassen verwirren möchte, sondern nur vier fünf Klassen die er wirklich braucht.
    Aber natürlich verhindert eine gute Dokumentation eine solch mögliche Verwirrung. Nur liest die immer keiner und postet dann zig Forenthreads mit Betreff "Wie kann ich..." / "Geht das oder nicht?" / "Keine Ahnung wo..."... (erinnert mich an mich selbst gerade)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!