Klasse von jedem Header aus zugreifbar machen in C++/CLI, und lösen des redefinition; different basic types Fehlers

  • C++/CLI

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von ClonkAndre.

    Klasse von jedem Header aus zugreifbar machen in C++/CLI, und lösen des redefinition; different basic types Fehlers

    Hallo liebe Community!
    Ich baue im Moment einen .NET Wrapper (C++/CLI) für ein C++ Projekt.

    Es lief bisher ganz gut, bis ich die Taste zum Kompilieren gedrückt habe :S
    In dem C++ Projekt ist es so, das manche Header Dateien, die vorher hinzugefügt (included) worden sind als andere, auf Klassen verweisen die erst später als die momentane Header Datei hinzugefügt worden ist.

    Beispiel:

    C-Quellcode

    1. #include "File1.h" // Verweist auf die Klasse "CVehicle" zum Beispiel mittels ein Feld oder einer Function
    2. #include "File2.h" // Beinhaltet die Klasse "CVehicle"


    Nun, dies ist kein Problem denn wir können dies ganz einfach mittels einer forward Declaration lösen (Welches das C++ Projekt auch nutzt).

    In meinem CLI Wrapper jedoch, sieht die Sache etwas anders aus.
    Ich habe genau die selbe Situation wie das C++ Projekt wo Klassen auf Klassen verweisen die erst später hinzugefügt werden.

    Nun... Wo ist das Problem? Ich könnte das Problem doch auch einfach mit forward Declarations lösen...
    Das habe ich versucht, das Problem ist nur, das die properties in diesem Fall, vesuchen auf ein Feld IN der Klasse zuzugreifen, und da diese Klasse nur eine forward Declaration ist, hat der compiler keine Ahnung das dieses Feld in dieser Klasse existiert (Soweit ich das verstanden habe)

    Echtes Beispiel aus meinem C+/CLI Wrapper Projekt:

    C-Quellcode

    1. // Dies ist in der pch.h Datei
    2. #include "IVSDKForwardDeclarations.h" // Dies beinhaltet all meine forward Declarations so das alle anderen Header Dateien die danach hinzugefügt werden Zugriff auf diese haben
    3. #include "IVPlayerInfo.h" // Dies beinhaltet eine Klasse die nicht nur auf die "IVVehicle" Klasse verweisen möchte, sondern auch auf ein Feld IN der "IVVehicle" zugreifen möchte.


    IVSDKForwardDeclarations.h:

    C-Quellcode

    1. ref class IVVehicle;


    IVPlayerInfo.h:

    C-Quellcode

    1. #pragma once
    2. namespace IVSDKDotNet
    3. {
    4. public ref class IVPlayerInfo
    5. {
    6. public:
    7. property IVVehicle^ OnlyEnterThisVehicle // Verweist auf die "IVVehicle" Klasse.
    8. {
    9. public:
    10. IVVehicle^ get()
    11. {
    12. NULLPTR_CHECK_WITH_RETURN(NativePlayerInfo, nullptr);
    13. NULLPTR_CHECK_WITH_RETURN(NativePlayerInfo->m_pOnlyEnterThisVehicle, nullptr);
    14. return gcnew IVVehicle(NativePlayerInfo->m_pOnlyEnterThisVehicle); // Versucht eine neue Instanz dieser Klasse zu erstellen.
    15. }
    16. void set(IVVehicle^ value)
    17. {
    18. NULLPTR_CHECK(NativePlayerInfo);
    19. NULLPTR_CHECK(NativePlayerInfo->m_pOnlyEnterThisVehicle);
    20. NULLPTR_CHECK(value);
    21. NativePlayerInfo->m_pOnlyEnterThisVehicle = value->NativeVehicle; // Versucht auf das "NativeVehicle" Feld in der "IVVehicle" Klasse zuzugreifen.
    22. }
    23. }
    24. public:
    25. static IVPed^ FindThePlayerPed(); // Für später interessant
    26. };
    27. }


    Bei Zeile 6 zeigt Visual Studio keinen Fehler beim kompilieren an.
    Bei Zeile 13 zeigt Visual Studio folgenen Fehler beim kompilieren: use of undefined type 'IVVehicle'
    Bei Zeile 20 zeigt Visual Studio folgenen Fehler beim kompilieren: use of undefined type 'IVVehicle'

    Klingt logisch für mich. Der Compiler hat keine Ahnung dass das Feld "NativeVehicle" in der "IVVehicle" Klasse existiert. Beim Constructor bin ich mir aber nicht sicher... Aber laut der Fehlermeldung hat der Compiler auch keine Ahnung das diese Klasse einen Constructor hat.

    Als nächstes habe ich versucht meine "IVVehicle" forward Declaration etwas zu ändern.
    IVSDKForwardDeclarations.h:

    C-Quellcode

    1. ref class IVVehicle
    2. {
    3. internal:
    4. IVVehicle(CVehicle* nativePtr);
    5. internal:
    6. CVehicle* NativeVehicle;
    7. };


    Nun beinhaltet die Klasse den Constructor und das Feld. (Kann man dies immernoch als "forward Declaration" bezeichnen?)
    Der Fehler verschwindete :!: Doch nun haben wir neue Fehler... Und dort weiß ich wirklich nicht mehr weiter...

    In der function definition für "static IVPed^ FindThePlayerPed();" in der "IVPlayerInfo" Klasse die so aussieht:

    C-Quellcode

    1. #include "pch.h"
    2. #include "IVPlayerInfo.h"
    3. namespace IVSDKDotNet
    4. {
    5. IVPed^ IVPlayerInfo::FindThePlayerPed()
    6. {
    7. CPed* ptr = FindPlayerPed();
    8. NULLPTR_CHECK_WITH_RETURN(ptr, nullptr);
    9. return gcnew IVPed(ptr);
    10. }
    11. }


    Zeigt Visual Studio nun bei Zeile 6 folgenen Fehler an: 'IVSDKDotNet::IVPlayerInfo::FindThePlayerPed': redefinition; different basic types
    Und bei Zeile 7: 'IVSDKDotNet::IVPed ^IVSDKDotNet::IVPlayerInfo::FindThePlayerPed(void)': overloaded function differs only by return type from 'IVPed ^IVSDKDotNet::IVPlayerInfo::FindThePlayerPed(void)'

    Worum handelt sich dieser Fehler genau? Und wie könnte ich ihn beheben?

    In meiner "IVSDKForwardDeclarations.h" Datei habe ich auch eine "forward Declaration" für die "IVPed" Klasse:

    C-Quellcode

    1. ref class IVPed
    2. {
    3. internal:
    4. IVPed(CPed* nativePed);
    5. internal:
    6. CPed* NativePed;
    7. };


    Falls ihr mehr Informationen benötigt, lasst es mich wissen!
    Danke!

    Nur zur Info: Bin absolut kein C++ Profi.
    Wenn ich dir auf irgendeiner Art und Weise helfen konnte, drück doch bitte den "Hilfreich" Button :thumbup:

    Für VB.NET Entwickler: Option Strict On nicht vergessen!
    Benutze .H und .CPP Dateien. Im Header die forward deklaration, in der CPP Datei dann den anderen Header includen.

    Also ich include sinnlos File2.h in File1.h, so kann ich durch den Includeguard(Ohne Includeguard, wäre das ja eine neu-definition), File1.h nicht in File2.h includen. Dann die froward deklaration im Header, aber in der File2.cpp kann ich File1.h includen. So ist File1 an der entscheidenden Stelle bekannt.

    Hab das Beispiel in C++ gemacht kein C++/CLI. Hab mit Managed C++ nichts am Hut.
    Main.cpp

    C-Quellcode

    1. #include <iostream>
    2. #include "File1.h"
    3. int main()
    4. {
    5. File1 file1 = File1();
    6. File2 file2 = File2();
    7. file2.DoSomething(file1);
    8. }


    File1.h

    C-Quellcode

    1. #pragma once
    2. #include "File2.h"
    3. class File1
    4. {
    5. public:
    6. int GetTheInt();
    7. };


    File1.cpp

    C-Quellcode

    1. #include "File1.h"
    2. int File1::GetTheInt()
    3. {
    4. return 1001;
    5. }


    File2.h

    C-Quellcode

    1. #pragma once
    2. #include <iostream>
    3. class File1;
    4. class File2
    5. {
    6. public:
    7. void PrintSomething();
    8. void DoSomething(File1 file1);
    9. };


    File2.cpp

    C-Quellcode

    1. #include "File2.h"
    2. #include "File1.h"
    3. void File2::PrintSomething()
    4. {
    5. }
    6. void File2::DoSomething(File1 file1)
    7. {
    8. std::cout << file1.GetTheInt() << std::endl;
    9. }

    Dateien
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „DTF“ ()