error C2664



  • Hallo,

    ich bin Neueinsteiger mit dieser Programmiersprache und versuche gerade ein Programm für eine Motorsteuerung zu realisieren. Ich habe dafür eine Klasse Position erstellt, in der ich alle Funktionen (z.B. Read_Position()) und die zugehörigen Variablen unterbringen möchte.

    //Ausschnitt der Headerdatei "Definitions.h"
    Initialisation_DllExport HANDLE __stdcall VCS_OpenDeviceDlg(DWORD* pErrorCode);
    

    Die Funktion ist in einer Headerdatei "Definitions.h" definiert, die ich in das Projekt eingebunden habe.

    Beim Kompilieren erhalte ich den Fehler C2664:
    1>------ Erstellen gestartet: Projekt: Motorsteuerung, Konfiguration: Debug Win32 ------
    1> Position.cpp
    1>Position.cpp(13): error C2664: 'VCS_OpenDeviceDlg': Konvertierung des Parameters 1 von 'cli::interior_ptr<Type>' in 'DWORD *' nicht möglich
    1> with
    1> [
    1> Type=DWORD
    1> ]
    1> Ein verwalteter Typ kann nicht in einen nicht verwalteten Typ umgewandelt werden
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========

    Worin könnte das Problem liegen? Ist der Adressoperator "&" falsch in C++/CLI?
    Wenn ich die Variable "DWORD ulErrorCode" local in der Funktion "Read_Position" deklariere, bringt der Compiler keinen Fehler.

    Besten Dank

    // Motorsteuerung.cpp: Hauptprojektdatei.
    
    #include "stdafx.h"
    
    #include "Position.h"
    #include "Velocity.h"
    
    using namespace System;
    
    int main(array<System::String ^> ^args)
    {
    
    	Console::WriteLine(L"Maxon Motorsteuerung");
    	return 0;
    }
    
    //Datei Position.h
    #pragma once
    #include "Definitions.h"
    using namespace System;
    ref class Position
    {
    	static	HANDLE	hNewKeyHandle	= 0;
    	static	DWORD	ulErrorCode		= 0;
    
    public:
    	Position(void);
    	long Read_Position(void);
    	long Set_Position(long);
    };
    
    //Datei Position.cpp
    #include "StdAfx.h"
    #include "Position.h"
    
    Position::Position(void)
    {
    
    }
    
    long Position::Read_Position(void)
    {
    	//DWORD	ulErrorCode		= 0;  Damit würde es funktionieren
    	hNewKeyHandle = VCS_OpenDeviceDlg(&ulErrorCode);
     	return 0;
    }
    
    long Position::Set_Position(long Position)
    {
    	return 0;
    }
    


  • Du hast die Variable in einer Managed-Klasse (ref class Position) untergebracht. Und dadurch kommt es zu diesem Fehler, da DWORD nichts weiter als ein Makro für "unsigned int" ist und in einer Managed-Klasse auf System::UInt32 abgebildet wird.
    Kapsel also alle Zugriffe auf native Funktionen in einer unmanaged-Klasse.



  • Th69 schrieb:

    Du hast die Variable in einer Managed-Klasse (ref class Position) untergebracht. Und dadurch kommt es zu diesem Fehler, da DWORD nichts weiter als ein Makro für "unsigned int" ist und in einer Managed-Klasse auf System::UInt32 abgebildet wird.
    Kapsel also alle Zugriffe auf native Funktionen in einer unmanaged-Klasse.

    Könntest Du mir das bitte noch etwas näher erklären? Und wie soll ich die Zugriffe kapseln, bzw. was müsste ich konkret verändern, damit ich die Funktion verwenden kann?



  • Ich habe versucht das Projekt mit einer nichtverwalteten Klasse zu erstellen, aber das funktioniert auch nicht. Ich bekomme dann eine andere Fehlermeldung:

    1>Testklasse.obj : error LNK2020: Nicht aufgelöstes Token (0A00001E) "private: static unsigned long Testklasse::ulErrorCode" (?ulErrorCode@Testklasse@@0KA).
    1>Testklasse.obj : error LNK2020: Nicht aufgelöstes Token (0A000020) "private: static void * Testklasse::hNewKeyHandle" (?hNewKeyHandle@Testklasse@@0PAXA).
    1>Testklasse.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""private: static void * Testklasse::hNewKeyHandle" (?hNewKeyHandle@Testklasse@@0PAXA)".
    1>Testklasse.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""private: static unsigned long Testklasse::ulErrorCode" (?ulErrorCode@Testklasse@@0KA)".
    1>c:\dokumente und einstellungen\sm\eigene dateien\visual studio 2010\Projects\Motorsteuerung\Debug\Motorsteuerung.exe : fatal error LNK1120: 4 nicht aufgelöste externe Verweise.
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========

    Irgendwie komme ich einfach nicht weiter. Kann mir vielleicht jemand noch etwas Starthilfe geben bitte?

    #pragma once
    #include "Definitions.h"
    
    using namespace System;
    class Testklasse
    {
    	static	HANDLE	hNewKeyHandle;
    	static	DWORD	ulErrorCode;
    public:
    	Testklasse(void);
    	~Testklasse(void);
    	long Read_Position(void);
    };
    
    #include "StdAfx.h"
    #include "Testklasse.h"
    
    Testklasse::Testklasse(void)
    {
    }
    
    Testklasse::~Testklasse(void)
    {
    }
    
    long Testklasse::Read_Position(void)
    {
    	hNewKeyHandle = VCS_OpenDeviceDlg(&ulErrorCode);
     	return 0;
    }
    
    // Motorsteuerung.cpp: Hauptprojektdatei.
    
    #include "stdafx.h"
    #include "Testklasse.h"
    
    using namespace System;
    
    int main(array<System::String ^> ^args)
    {
    
    	Console::WriteLine(L"Maxon Motorsteuerung");
    	return 0;
    }
    


  • Warum verwendest du überhaupt statische Member?
    Ansonsten mußt du statische (native) Member auch noch in der Source-Datei definieren.

    Und generelle Frage: benötigst du überhaupt eine managed-Umgebung (d.h. das .NET-Framework)? Ansonsten nimm natives C++ mit einem reinem "Win32-Konsolenprojekt".



  • Hallo,

    also ich muss vielleicht etwas weiter ausholen. Ich habe für die Motorsteuerung 3 Dateien, die ich ins Projekt einbinden muss: EposCmd.dll, EposCmd.lib und Definitions.h
    Definitions.h habe ich in der Headerdatei Positions.h per include eingebunden, die Bibliothek ist über Projekteigenschaften->Linker->Input bei zusätzliche Abhängigkeiten angemeldet. Alle 3 Dateien befinden sich im Projektordner.

    Der Motor hat verschiedene Profile z.B. bestimmte Position anfahren, Geschwindigkeitsregelung, Drehmomentregelung etc.

    Um beispielsweise eine bestimmte Position auszulesen, sind verschiedene Funktionen (Definitions.h) nacheinander aufzurufen.
    Ich möchte letztendlich für jedes Profil eine eigene Klasse als Methodensammlung anlegen (es werden keine Instanzen erzeugt). Deswegen sollte (so habe ichs im Buch von D.Louis gelesen) statische Felder (Klassenvariable) und Methoden definiert werden.

    "Klassenvariablen sind die einzigen Datenelemente einer Klasse, auf die statische Methoden zugreifen können. Für Klassen, die lediglich als Methodensammlung dienen (und gar nicht instanziert werden), sind sie also die einzigen in Frage kommenden Datenelemente überhaupt.
    ...
    Statische Methoden findet man vor allem in Klassen, die wie Math als reine Methodensammlung dienen..."

    Mein Ziel ist am Ende ein GUI-Programm, deswegen möchte ich das .NET-Framework verwenden (und weil ich mich durch den Kauf des Buches letztendlich festgelegt habe und nach Möglichkeit nicht mehr wechseln möchte).

    1. Das Problem (Verständnisproblem) was ich habe ist, wie verwende ich am besten diese Funktionen aus der Bibliothek welche wahrscheinlich nicht verwaltet ist in einem sonst verwalteten Projekt (ref class...).

    2. Wo und wie muss ich die für die Funktionsparameter benötigten Variablen deklarieren und initialisieren.

    3. D.h. mir ist auch noch nicht ganz klar wie das "Grundgerüst" aussehen muss.

    4. Wieso wird in einer nichtverwalteten Klasse der Konstruktor ein 2. Mal mit einer vorangestellten Tilde (~) eingefügt (siehe Codebeispiel vom 15:44:17 18.11.2011)?

    Ich habe noch etwas herumexperimentiert (anders kann man es nicht bezeichnen) und die nachfolgende fehlerfreie Lösung auch mit einer verwalteten Klasse gefunden. Allerdings weiss ich nicht, ob diese so ausbaufähig ist, oder ob ich irgendwann Probleme bekomme.
    Vielleicht könnte mir bitte jemand konkret an diesem Beispiel erläutern, was ich falsch mache oder verbessern könnte. Bisher habe ich ausschliesslich in C programmiert, hauptsächlich uC. Deswegen habe ich etwas Mühe das viele "Fachchinesisch" der OOP zu verstehen und wäre eben an einer "beispielhaften Erklärung" sehr interessiert:

    Für Eure Hilfe wäre ich sehr dankbar.

    // Motorsteuerung.cpp: Hauptprojektdatei.
    
    #include "stdafx.h"
    #include "Position.h"
    
    using namespace System;
    
    int main(array<System::String ^> ^args)
    {
    	long Stellung=0;
    	Console::WriteLine(L"Maxon Motorsteuerung");
    	Stellung=Position::Read_Position();
    	Console::WriteLine(L"Position ist: " + Stellung);
    	Console::ReadLine();
    	return 0;
    }
    
    //Datei Position.h
    #pragma once
    #include "Definitions.h"
    using namespace System;
    ref class Position
    {
    private:
    	Position(void);
    public:
    	static long Read_Position(void);
    };
    
    //Datei Position.cpp
    #include "StdAfx.h"
    #include "Position.h"
    
    HANDLE	hNewKeyHandle	= 0;
    DWORD	ulErrorCode		= 0;
    WORD	usNodeId		= 1;
    long	gelesenePosition = 0;
    
    Position::Position(void)
    {
    	//Konstruktor private, keine Erzeugung von Objekten
    }
    
    long Position::Read_Position(void)
    {
    	hNewKeyHandle = VCS_OpenDeviceDlg(&ulErrorCode);
        if(hNewKeyHandle)
        {
    		//...
    		VCS_GetPositionIs(hNewKeyHandle, usNodeId, &gelesenePosition, &ulErrorCode);
    		//...
        }
        else
        {
    		Console::WriteLine("Can not open device!");
        }
    
     	return gelesenePosition;
    
    }
    


  • Sorry micsch, aber C++/CLI ist dafür definitiv die falsche Programmiersprache, s.a. Windows Forms und Visual C++ MACHT KEINEN SINN!.
    Und gerade bei deinen Programmierkenntnissen kann ich nur davon abraten - um C++/CLI verwenden zu können, muß man sowohl in nativem C++ als auch mit der .NET-Programmierung sich sehr gut auskennen.

    Entweder natives C++ und ein GUI-Framework (s. [HOWTO] Welches Toolkit für GUIS?) oder aber C# mit dem .NET-Framework (und evtl. der Einbindung einer C bzw. C++ DLL mittels [DllImport]).



  • Hallo TH69,

    danke für Deinen Hinweis. Den Link "Windows Forms und Visual C++ MACHT KEINEN SINN!" habe ich bereits gelesen, allerdings erst nachdem ich mein Buch "jetzt lerne ich Visual C++ 2010" gekauft und zur Hälfte gelesen habe. Es kann schon sein, dass Windows Forms und VC++ keinen Sinn macht, aber d.h. nicht das es unmöglich ist. Was meine Programmierkenntnisse anbelangt, magst Du was die OOP betrifft Recht haben. Ich bin eben gerade dabei mich in dieses Gebiet einzarbeiten, d.h. aber nicht dass ich mich mit programmieren gar nicht auskenne. Es sind halt manche Dinge aus C++ und .NET-Framework neu für mich. Ich muss auch jetzt in dieser Sprache kein Profi werden, sondern ich bräuchte lediglich ein wenig Starthilfe für den Anfang wie einen Beitrag vorher beschrieben, wo ich drauf aufbauen kann.


Anmelden zum Antworten