C++ Function: Return pointer oder Pointer als Reference



  • Hi,

    versuche gerade ne DLL zu schreiben mit VC++2010pro die ich dann unter .Net einbinden will.

    In der Dll ist ne Function die mir einen int pointer auf ein int-array als reference zurückgeben soll, oder aber auch ein Pointer als Rückgabewert direkt.
    Hab beides versucht klappt aber irgendwie beides nicht.

    Soweit ich das verstanden hab, wenn ich einem int-pointer das array zuweise enthält der pointer die adresse auf das erste element, und dann sollte mein code eigentlich funktionieren. Kompilieren funzt auch.

    Hier mal die Funktion:

    __declspec(dllexport) int GetPointerAsRef(char inChar, int *& refint)
      {
    	  int aforward[6] = {1, 2, 3, 4, 5, 6};
    	  int areverse[6] = {6, 5, 4, 3, 2, 1};
    
        int p=0;
    
    	if(inChar == 'f')  {
      		refint=aforward;
    		p=1;
        }
        if(inChar == 'r')  {
           refint=areverse;
    	   p=1;
        }
    
        return p;
    
      }
    

    Und der Aufruf in .Net: (egal ob c# oder vb.net)

    Deklaration:

    <DllImport("Test.dll")> _
        Public Shared Function GetPointerAsRef(ByVal inChar As Char, ByRef myPointer As IntPtr) As Integer
        End Function
    

    Aufruf:

    Dim mypt as IntPtr = Nothing
    Dim myresult As Integer = GetPointerAsRef("f", mypt)
    

    Fehlermeldung ist dann immer: PInvokeStackImbalance wurde erkannt.

    Message: Ein Aufruf an die PInvoke-Funktion GetPointerAsRef hat das Gleichgewicht des Stapels gestört.
    Wahrscheinlich stimmt die verwaltete PInvoke-Signatur nicht mit der nicht verwalteten Zielsignatur überein.
    Überprüfen Sie, ob die Aufrufkonvention und die Parameter der PInvoke-Signatur mit der nicht verwalteten Zielsignatur übereinstimmen.

    Bin noch ziemlicher Anfänger in c++ vondem her wärs nett wenn mir jemand weiterhelfen könnte.

    Thx schonmal



  • Du solltest in den öffentlichen Funktionen keine Referenzen verwenden. C kennt nur Pointer.

    Wenn du das Array so definierst wird es am Ende der Funktion zerstört.

    Lösungsmöglichkeiten

    1. das Array statisch machen

    2. das Array global machen in der DLL

    3. den benötigten Speicher von aussen übergeben

    4. ist wohl die "sauberste" Lösung, allerdings mit etwas Aufwand beim Aufrufer verbunden. Hier muss die C# Anwendung genug Speicher reservieren. Hierzu kannst (musst?) du Marshal.AllocHGlobal() http://msdn.microsoft.com/en-us/library/aa330452(v=vs.71).aspx verwenden

    __declspec(dllexport) int GetPointerAsRef(char inChar, int* refint)
      {
          static int aforward[6] = {1, 2, 3, 4, 5, 6};
          static int areverse[6] = {6, 5, 4, 3, 2, 1};
    
        int p=0;
    
        if(inChar == 'f')  {
            refint=aforward;
            p=1;
        }
        if(inChar == 'r')  {
           refint=areverse;
           p=1;
        }
    
        return p;
    
      }
    
    int aforward[6] = {1, 2, 3, 4, 5, 6};
    int areverse[6] = {6, 5, 4, 3, 2, 1};
    __declspec(dllexport) int GetPointerAsRef(char inChar, int* refint)
      {
        int p=0;
    
        if(inChar == 'f')  {
            refint=aforward;
            p=1;
        }
        if(inChar == 'r')  {
           refint=areverse;
           p=1;
        }
    
        return p;
    
      }
    
    __declspec(dllexport) int GetPointerAsRef(char inChar, int* refint,size_t refIntSize)
      {
        int aforward[6] = {1, 2, 3, 4, 5, 6};
        int areverse[6] = {6, 5, 4, 3, 2, 1};
        int p=0;
    
        if(inChar == 'f')  {
            const size_t size = std::min(refIntSize,6);
            memcpy(refint,aforward,size);
            p=1;
        }
        if(inChar == 'r')  {
           const size_t size = std::min(refIntSize,6);
           memcpy(refint,areverse,size);
           p=1;
        }
    
        return p;
    
      }
    

Anmelden zum Antworten