Eine Funktion in zwei cpp-Dateien, "multiply defined symbols found"



  • Hallo,

    hier eine wohl typische Anfängerfrage:
    Ich habe eine Datei CC.cpp und eine D.cpp
    In beiden Dateien benötige ich eine Funktion "LRESULT CALLBACK LowLevelKeyboardProc".
    Ich habe nun in beide cpp-Dateien die Funktionsdefinition reingeschrieben.
    Zudem habe ich bei beiden <Windows.h> included.
    Beide nutzen zudem eine Datei v.h

    Der Linker bringt nun aber die Fehlermeldung "D.obj:error LNK2005:..LowLevelKeyboardProc.. one or more multiply defined symbols found"

    Was muss ich ändern? Kann ich die Funktionsdefinition in die Datei v.h reinsetzen, da ja beide cpp-Dateien diese includen?

    Danke schon mal für die Hilfe!



  • Du musst die "Deklaration" in der h-Datei vornehmen und die "implementation" in *einer* CPP-Datei...

    Also H.-Datei:

    void Func1();
    

    In *einer* CPP-Datei:

    void Func1()
    {
      // Do something...
    }
    


  • Mache ich die Deklaration in der v.h-Datei?
    Die Implementation in der v.cpp-Datei?



  • 👍



  • Die Deklaration kommt in die v.h (die von allen .CPP eingebunden werden sollte, die diese Funktion benötigen), die Implementation in eine der .CPP Dateien (ob du dafür eine neue v.cpp verwendest oder eine der vorhandenen Dateien, ist dabei egal - solange es genau eine ist).



  • Die Implementation der Funktion benötigt noch die folgenden Zeilen:

    #define _WIN32_WINNT 0x0400
    #include <Windows.h>
    

    Kommen diese auch in die Headerdatei od. in jede cpp-Datei?



  • Am besten in die Projekteinstellungen für das ganze Projekt (Project|Properties|C/C++|Preprocessor|Preprocessor Definitions".
    Dann solltest Du auch gleich WINVER und _WIN32_IE definieren!

    Siehe: Using the Windows Headers
    http://msdn.microsoft.com/library/en-us/winprog/winprog/using_the_windows_headers.asp



  • Aber das include windows.h steht nur in der v.cpp (denke ich mir mal).

    Jetzt erscheint aber folgender Fehler:

    C:\Programme\Microsoft Visual Studio\VC98\INCLUDE\xstring(133) : error C2129: static function 'long __stdcall LowLevelKeyboardProc(int,unsigned int,long)' declared but not defined
    see declaration of 'LowLevelKeyboardProc'.

    Was soll denn das?



  • Du musst diese Funktion natürlich irgendwo implementieren! Und dass in geneu *einer* CPP-Datei!



  • Jaaa, habe ich doch gemacht, nämlich so:
    In der v.h-Datei:

    static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
    

    In der v.cpp-Datei:

    static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
       BOOL fEatKeystroke = FALSE;
    
       if (nCode == HC_ACTION) {
          switch (wParam) {
          case WM_KEYDOWN:  case WM_SYSKEYDOWN:
          case WM_KEYUP:    case WM_SYSKEYUP:
             PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam;
             fEatKeystroke =
                ((p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) ||
                ((p->vkCode == VK_ESCAPE) && ((p->flags & LLKHF_ALTDOWN) != 0)) ||
                ((p->vkCode == VK_ESCAPE) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0));
             break;
          }
       }
       return(fEatKeystroke ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam));
    }
    


  • lass mal das "static" weg, damit schränkst du den Sichtbarkeitsbereich der Funktion zu sehr ein.

    (static Funktionen sind nur in ihrer eigenen Übersetzungseinheit verfügbar, das widerspricht sich mit deinem Versuch, die Funktion in mehreren Teilprogrammen zu nutzen)



  • Das habe ich mir schon fast gedacht. OK, die Fehlermeldung ist weg.

    Aber nun bringt mir der Linker die Meldung:
    error LNK2005: "struct HHOOK__ * hhkLowLevelKybd" (?hhkLowLevelKybd@@3PAUHHOOK__@@A) already defined in AboutBox.obj
    ...
    fatal error LNK1169: one or more multiply defined symbols found

    Ich habe in der v.h-Datei die Deklaration stehen:

    HHOOK hhkLowLevelKybd;
    

    In diversen cpp-Dateien steht die Befehlszeile

    UnhookWindowsHookEx(hhkLowLevelKybd);
    


  • in der v.h benötigst du dafür:

    extern HHOOK hhkLowLevelKybd;//reine Deklaration
    //nur zur Sicherheit:
    LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
    

    die dazugehörige v.cpp:

    #include "v.h"
    HHOOK hhkLowLevelKybd;//zugehörige Definition
    LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
      //Implementation
    }
    

    (Falls du noch andere globale Variablen und Funktionen hast - da gilt das selbe: Im Header deklarieren (Prototyp bzw. extern-Variable), im Quellfile definieren (Implementation bzw. Variablendefinition))



  • Ein großes DANKESCHÖÖÖN!!!!


Anmelden zum Antworten