Wechsel VS2008 zu VS2010: Danach Fehler C2733 (2. C-Bindung für überladene Funktion nicht zulässig)



  • Hallo allerseits,

    ich habe ein kleines DLL Projekt in VS2008 geschrieben. Dort lief alles wunderbar. Anschließend musste ich zu Visual Studio 2010 wechseln. Ab dort tritt nun folgender Fehler auf:

    Fehler 1 error C2733: Zweite C-Bindung für überladene Funktion 'FunctionName' nicht zulässig

    in der cpp datei ist folgender code:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    	__declspec(dllexport)bool FunctionName(void);
            //[...noch mehr davon...]
    #ifdef __cplusplus
    } // extern "C"
    #endif
    

    Dazu gehört dann auch noch die eigentliche Funktion:

    bool FunctionName(void)
    {
            //[... inhalt ...]
    	return true;
    
    }
    

    Wie gesagt, mit Visual Studio 2008 lief es, mit 2010 nicht mehr. Hat vielleicht jemand eine Idee, wie ich es wieder zum laufen bringe?

    Vielen Dank im Voraus.

    Gruß,
    Felix


  • Mod

    Diese Zeilen alleine bringen keinen Fehler.

    Die Funktion muss zweimal definiert sein, sonst käme es nciht zu dieser Fehlermeldung.



  • Genau davon bin ich auch ausgegangen. Aber die Funktion wird kein zweites Mal definiert. 😕

    Wie oben geschrieben, erst der Wechsel von Visual Studio 2008 zu 2010 brachte den Fehler hervor.


  • Mod

    Dann zeig mal minmalen Code, der diesen Fehler erzeugt.



  • Ich kann die Zeile des dllexports auskommentieren, dann kann ich als release kompilieren. Bringt mir aber nichts, denn das Programm was diese DLL nutzt hat dann keinen Zugriff mehr auf diese Funktion.

    Als Debug kann ich es ohne die Zeile nicht kompilieren. Da kommen dann folgende Fehler:

    Warnung 1 warning C4190: 'GetMessageLastError' hat C-Bindung angegeben, aber gibt UDT 'ATL::CStringT<BaseType,StringTraits>' zurück, was mit C inkompatibel ist
    Fehler 2 error LNK2005: __initp_misc_invarg ist bereits in libcmtd.lib(invarg.obj) definiert.
    Fehler 3 error LNK2005: __call_reportfault ist bereits in libcmtd.lib(invarg.obj) definiert.
    Fehler 4 error LNK2005: __set_invalid_parameter_handler ist bereits in libcmtd.lib(invarg.obj) definiert.
    Fehler 5 error LNK2005: __get_invalid_parameter_handler ist bereits in libcmtd.lib(invarg.obj) definiert.
    Fehler 6 error LNK2005: __invoke_watson ist bereits in libcmtd.lib(invarg.obj) definiert.
    Fehler 7 error LNK2005: "void __cdecl _invoke_watson(unsigned short const *,unsigned short const *,unsigned short const *,unsigned int,unsigned int)" (?_invoke_watson@@YAXPBG00II@Z) ist bereits in libcmtd.lib(invarg.obj) definiert.
    Fehler 8 error LNK2005: __invalid_parameter ist bereits in libcmtd.lib(invarg.obj) definiert.
    Fehler 9 error LNK2005: "void __cdecl _invalid_parameter(unsigned short const *,unsigned short const *,unsigned short const *,unsigned int,unsigned int)" (?_invalid_parameter@@YAXPBG00II@Z) ist bereits in libcmtd.lib(invarg.obj) definiert.
    Fehler 10 error LNK2005: ___pInvalidArgHandler ist bereits in libcmtd.lib(invarg.obj) definiert.
    Warnung 11 warning LNK4098: Standardbibliothek "LIBCMT" steht in Konflikt mit anderen Bibliotheken; /NODEFAULTLIB:Bibliothek verwenden.
    Fehler 12 error LNK1169: Mindestens ein mehrfach definiertes Symbol gefunden.

    Die erste Warnung kommt immer mit dabei, egal wie kompiliert wird und egal was auskommentiert wird.

    Du möchtest nun Code haben, den du bei dir kompilieren kannst um den Fehler nachvollziehen zu können, oder habe ich das falsch verstanden?

    Wenn ja, dann hier:

    // CounterDummy.cpp
    //
    #include "stdafx.h"
    #include "CounterDummy.h"
    #include <iostream>
    #include <sstream>
    
    extern "C" __declspec(dllexport)bool OpenTransaction(void);
    
    void Log(CString strLog);
    
    BEGIN_MESSAGE_MAP(CCounterDummyApp, CWinApp)
    END_MESSAGE_MAP()
    
    CCounterDummyApp::CCounterDummyApp()
    {
    }
    
    CCounterDummyApp theApp;
    
    BOOL CCounterDummyApp::InitInstance()
    {
    	CWinApp::InitInstance();
    
    	CRegKey RegKey;
    	DWORD dwBuf; 
        DWORD dwBufferSize = MAX_PATH;
    
    	return TRUE;
    }
    
    bool OpenTransaction(void)
    {
    	return true;
    }
    
    // CounterDummy.h
    //
    #pragma once
    
    #ifndef __AFXWIN_H__
    	#error "'stdafx.h' vor dieser Datei für PCH einschließen"
    #endif
    
    #include "resource.h"		// Hauptsymbole
    #include <fstream>
    #include <strstream>
    #include <atlbase.h>
    #include <xmllite.h>
    using namespace std;
    
    class CCounterDummyApp : public CWinApp
    {
    public:
    	CCounterDummyApp();
    public:
    	virtual BOOL InitInstance();
    
    	DECLARE_MESSAGE_MAP()
    };
    

  • Mod

    1. Die Linker-Fehler resultieren daraus, dass Du die afx.h nicht vor den anderen includes eingebaut hast.

    2. extern "C" und bool? Das geht ja wohl nicht. C kennt kein bool!

    3. Wenn Du schon so deklarierst:

    extern "C" __declspec(dllexport) BOOL OpenTransaction(void);
    

    Musst Du auch so definieren:

    extern "C" BOOL OpenTransaction(void)
    {
        return TRUE;
    }
    

    4. Du kannst Dir die Deklaration hier komplett sparen! Du kannst auch einfach nur definieren:

    extern "C" __declspec(dllexport) BOOL OpenTransaction(void)
    {
        return TRUE;
    }
    


  • Vielen Dank! Das sind schonmal super Sachen!
    Die stdafx.h ist doch als erstes drin, oer nicht?

    Der Fehler "error C2733: Zweite C-Bindung für überladene Funktion 'OpenTransaction' nicht zulässig" ist jedoch leider immernoch vorhanden.

    Außerdem wird auch immer kurz dieser Fehler angezeigt, verschwindet dann aber schnell wieder wenn ich an der Stelle bin (war auch vorher schon so):
    IntelliSense: Mindestens eine Instanz der überladenen Funktion ""OpenTransaction"" weist eine "C"-Verknüpfung auf.



  • In ktmw32.h ist noch ein BOOL OpenTransaction vorhanden.
    Was kann ich nun machen?

    Testweise habe ich den Bereich in ktmw32.h auskommentiert. Das will ich natürlich nicht so lassen.
    Nun bekomme ich wieder die Linker-Fehler. Wie genau kann ich diese wegbekommen?



  • Hallo,

    OpenTransaction ist doch eine API-Funktion, die du nicht selbst definiert hast? Dann ist auch keine eigene Deklaration notwendig.

    MfG,

    Probe-Nutzer



  • Sehe gerade, hast du doch selber definiert. Dann darf deine Funktion eben nicht OpenTransaction heissen, wenn du ktmw32.h unbedingt includieren musst.

    MfG,

    Probe-Nutzer



  • Das ist mir mittlerweile ja bewusst. Leider habe ich gerade keine andere Möglichkeit, als sie genau so zu nennen da die Funktion von anderen Programmen genau so genutzt werden soll.

    Ob ich die ktmw32.h wirklich brauche, weiß ich nicht. Sie kommt ja von den Windows SKDs. Habe das Projekt so übernommen und muss selber erst schauen, was wo gebraucht wird. Schaue gerade, wo denn steht, dass ich diese Datei wirklich benötige bzw. wo sie inkludiert wird. Bisher konnte ich dazu nichts finden. Sie steht auf jeden Fall mit bei den 'externen Abhängigkeiten'.



  • Die Kette könnte lauten atlbase.h - atltransactionmanager.h - ktmw32.h. Wenn man vorher _KTMUSER_ #definiert, kommt der Fehler nicht mehr. Dafür kann man nicht mehr die Transaction-Funktionen verwenden. Und man muss hoffen, dass der Linker deine Funktion nicht mit der aus der Ktmw32.dll "verwechselt".

    Ist leider so, MS scheint es nicht für nötig zu halten, ihren Funktionen und Defines einen Präfix zu geben. Auf der anderen Seite hätte der Verantwortliche für deine Bibliothek von Anfang an Präfixe für die Funktionsnamen schaffen müssen. Das ist das A und O von C-Schnittstellen.


  • Mod

    Und warum arbeitest Du nicht mit einer DEF Datei?

    http://msdn.microsoft.com/en-us/library/hyx1zcd3(VS.71).aspx

    entryname[=internalname]
    

    Nenne das Ding MyOpenTransaction. In der Def Datei setzt Du dann in der Exports Section!

    OpenTransaction=MyOpenTransaction
    


  • Das ändert aber nichts an der Namenskollision für Benutzer der Lib. Wenn sie ATL und flixLib zusammen in einer translation unit verwenden wollen, fliegen sie erst mal auf die Nase.


  • Mod

    Superlexx schrieb:

    Das ändert aber nichts an der Namenskollision für Benutzer der Lib. Wenn sie ATL und flixLib zusammen in einer translation unit verwenden wollen, fliegen sie erst mal auf die Nase.

    Das ist korrekt. Aber Implizites laden wäre möglich.
    Und wenn der DLL extern vorgeschrieben ist, kann ich mir nicht vorstellen, dass dieses Proble bei jeder Vorgängerversion von VS-200x nicht auch vorhanden war, sofern eben das Vista SDK (oder später) verwendet wird.

    Bleibt also immer noch die Option einfach nur bis Windows XP die defines für die Header zu setzen.
    Siehe http://msdn.microsoft.com/en-us/library/aa366315(VS.85).aspx



  • Vielen Dank an alle. Ich habe es nun vorerst mit Hilfe der DEF Datei gelöst.
    Stehe aber auch mit den Leuten in Kontakt, die die Namensvergabe gemacht haben. Somit lässt sich dort evtl. noch etwas ändern.

    Die Linker Fehler sind alle weg - somit läuft vorerst alles. Ich habe zwar noch ein anderes Problem, aber dafür würde ich, wenn ich es nicht gelöst bekomme, wohl einen neuen Thread eröffnen.

    Vielen Dank an alle, Ihr habt mir sehr geholfen. 👍


Anmelden zum Antworten