Verweis auf nicht aufgelöstes externes Symbol



  • Hallo,

    ich möchte ein fertigen Code comilieren und linken, der also schon funktionstüchtig sein müsste. Wenn ich ihn (mit VisualStudio2008) im release-Modus übersetze, funktioniert das Programm wunderbar. Versuche ich das ganze jedoch im debug-Modus, bekomme ich folgende Fehlermeldungen:

    1>------ Erstellen gestartet: Projekt: Memmng, Konfiguration: debug Win32 ------
    1>Verknüpfen...
    1>Memmng.obj : warning LNK4075: /EDITANDCONTINUE wird aufgrund der Angabe von /INCREMENTAL:NO ignoriert.
    1>Plda_api.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_InterruptEnable@20" in Funktion "_PldaInitializeKerplugInterrupt".
    1>Plda_api.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_InterruptDisable@4" in Funktion "_PldaReleaseInterrupt".
    1>.\Debug/Memmng.exe : fatal error LNK1120: 2 nicht aufgelöste externe Verweise.
    1>Das Buildprotokoll wurde unter "file://d:\entwicklung\sw\Memmng\Debug\BuildLog.htm" gespeichert.
    1>Memmng - 3 Fehler, 1 Warnung(en)
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========

    Kann mir vielleicht jemand sagen was mein Fehler ist?
    Danke im voraus.



  • Zeig mal ein wenig Code...
    Vielleicht vergessen eine Lib zu linken?



  • Ich weiß leider nicht welchen Teil ich am besten zeigen sollte. Es sind sehr viele Dateien und alle ein zu stellen ist sicher nicht sinnvoll.

    Das einzige in dem ich etwas von z.B. "PldaInitializeKerplugInterrupt" finden kann (der Fehler bemängelt jedoch "_PldaInitializeKerplugInterrupt") ist im nachfolgenden Code, in dessen Headerdatei und in der Datei, in der er ausgeführt werden soll.

    Die gesamte Anwendung (in die ich mich hier einarbeiten soll) soll per PCIe auf den Speicher einer Steckkarte zugreifen können.

    Ausschnitt:

    /*************************************************************************************
    **
    ** Initialise interrupt
    **
    *************************************************************************************/

    DWORD PldaInitializeKerplugInterrupt (DWORD PCIAgentIndex,PVOID pData,INT_PLDA_HANDLER pPldaIntHandler)
    {
    BZERO(g_Int[PCIAgentIndex]);

    /* Check if interrupt can be initialised */
    if (g_hWD == INVALID_HANDLE_VALUE) return FALSE;
    if (g_PCIResources[PCIAgentIndex].hInterrupt == 0) return FALSE;
    if (g_PCIResources[PCIAgentIndex].hThread != 0) return FALSE;
    if (g_kerPlugin.hKernelPlugIn==0) return FALSE;

    /* Set-up interrupt structure */
    g_Int[PCIAgentIndex].hInterrupt=g_PCIResources[PCIAgentIndex].hInterrupt;
    g_Int[PCIAgentIndex].kpCall.hKernelPlugIn=g_kerPlugin.hKernelPlugIn;
    g_Int[PCIAgentIndex].kpCall.pData=pData;

    g_PCIResources[PCIAgentIndex].IntCount = 0;

    if (!InterruptEnable( &g_PCIResources[PCIAgentIndex].hThread, g_hWD, &g_Int[PCIAgentIndex], (INT_PLDA_HANDLER) pPldaIntHandler,NULL))
    return FALSE;

    return TRUE;
    }

    DWORD PldaInitializeInterrupt(DWORD PCIAgentIndex, SPCIInterruptTransfer* pPCIInterruptTransfer, INT_PLDA_HANDLER pPldaIntHandler)
    {
    BZERO(g_Int[PCIAgentIndex]);
    BZERO(g_Trans[PCIAgentIndex][0]);
    BZERO(g_Trans[PCIAgentIndex][1]);

    if (g_hWD == INVALID_HANDLE_VALUE)
    return FALSE;

    if (g_PCIResources[PCIAgentIndex].hInterrupt == 0)
    return FALSE;

    if (g_PCIResources[PCIAgentIndex].hThread != 0)
    return FALSE;

    g_Trans[PCIAgentIndex][0].dwPort = g_PCIResources[PCIAgentIndex].BARUserAddress[pPCIInterruptTransfer->BarIndex]
    + pPCIInterruptTransfer->ByteOffset;
    g_Trans[PCIAgentIndex][0].Data.Dword = pPCIInterruptTransfer->ResetValue;

    switch (pPCIInterruptTransfer->AccessType)
    {
    case ISR_READ:
    g_Trans[PCIAgentIndex][0].cmdTrans = RM_DWORD;
    g_Int[PCIAgentIndex].dwCmds = 1;
    break;
    case ISR_WRITE:
    g_Trans[PCIAgentIndex][0].cmdTrans = WM_DWORD;
    g_Int[PCIAgentIndex].dwCmds = 1;
    break;
    case ISR_RW:
    g_Trans[PCIAgentIndex][0].cmdTrans = RM_DWORD;
    g_Trans[PCIAgentIndex][1].cmdTrans = WM_DWORD;
    g_Trans[PCIAgentIndex][1].dwPort =g_Trans[PCIAgentIndex][0].dwPort;
    g_Trans[PCIAgentIndex][1].Data.Dword =g_Trans[PCIAgentIndex][0].Data.Dword;
    g_Int[PCIAgentIndex].dwCmds = 2;
    break;
    default: return FALSE;
    }

    /* Indicate that interrupt is handled by kernel plug-in */
    if (g_kerPlugin.hKernelPlugIn!=0)
    g_Int[PCIAgentIndex].kpCall.hKernelPlugIn=g_kerPlugin.hKernelPlugIn;

    g_Int[PCIAgentIndex].hInterrupt = g_PCIResources[PCIAgentIndex].hInterrupt;
    g_Int[PCIAgentIndex].Cmd = g_Trans[PCIAgentIndex];

    g_Int[PCIAgentIndex].dwOptions |= INTERRUPT_CMD_COPY;

    g_PCIResources[PCIAgentIndex].IntCount = 0;

    if (!InterruptEnable(
    &g_PCIResources[PCIAgentIndex].hThread,
    g_hWD,
    &g_Int[PCIAgentIndex],
    (INT_PLDA_HANDLER) pPldaIntHandler,
    (void*)&g_Int[PCIAgentIndex]))
    return FALSE;

    return TRUE;
    }

    /*************************************************************************************
    **
    ** Release interrupt
    **
    *************************************************************************************/

    DWORD PldaReleaseInterrupt(DWORD PCIAgentIndex)
    {
    if (g_hWD == INVALID_HANDLE_VALUE) return FALSE;
    if (g_PCIResources[PCIAgentIndex].hInterrupt == 0) return FALSE;
    if (g_PCIResources[PCIAgentIndex].hThread == 0) return FALSE;

    InterruptDisable(g_PCIResources[PCIAgentIndex].hThread);
    g_PCIResources[PCIAgentIndex].hThread = NULL;

    return TRUE;
    }



  • Wie gesagt. Das hat nichts mit dem Code zu tun. Das sind Linkerfehler.
    Du musst also nochmal schauen, ob die du lib richtig einbindest.



  • Dieses C++ macht mich echt zu schaffen. (bin eher ein C-Programmierer)

    Ich dachte mir ich kommentiere jetzt einfach mal alles, bis auf die main-Schleife aus um wenigstens einen Teil des Programmes im Debug-Modus durch"steppen" zu können, aber es gibt überhaupt kein main.
    Wo fängt denn dann das Programm an seinen Code ab zu arbeiten?

    (Sorry für diese Anfängerfrage. Habe mich um diese Aufgabe nicht gerade gerissen 🙂 Kann meinem Chef aber leider nicht einfach sagen, dass ich es nicht machen möchte. Eigentlich will ich will ich das ja auch gar nicht aufgeben)



  • Hans_Wurst schrieb:

    Dieses C++ macht mich echt zu schaffen. (bin eher ein C-Programmierer)

    Der Code da oben sieht auch irgendwie nicht nach C++ aus sondern eher wie C. 🙂
    Es gibt definitiv eine Main-Funktion. Sie heißt evtl. anders. Das hängt jetzt von deiner verwendeten API ab.



  • Hans_Wurst schrieb:

    Dieses C++ macht mich echt zu schaffen. (bin eher ein C-Programmierer)

    Das gepostete ist C. Pur.

    Ich dachte mir ich kommentiere jetzt einfach mal alles, bis auf die main-Schleife aus um wenigstens einen Teil des Programmes im Debug-Modus durch"steppen" zu können, aber es gibt überhaupt kein main.
    Wo fängt denn dann das Programm an seinen Code ab zu arbeiten?

    Bei WinAPI-Software ist der Einstiegspunkt z.B. WinMain.

    Das einzige in dem ich etwas von z.B. "PldaInitializeKerplugInterrupt" finden kann (der Fehler bemängelt jedoch "_PldaInitializeKerplugInterrupt") ist im nachfolgenden Code, in dessen Headerdatei und in der Datei, in der er ausgeführt werden soll.

    Richtig, und darin werden die unbekannten Funktionen InterruptEnable und InterruptDisable benutzt. Da das keine WinAPI-Funktionen sind (ich konnte sie in der MSDN jedenfalls nicht finden), musst Du rausfinden in welcher Bibliothek die sind. Da können wir Dir nicht helfen, es seidenn jemand hat diese Bibliothek zufällig auch schon benutzt 🙂

    EDIT: Gehören die vielleicht zum DDK (Driver Development Kit)?



  • Hans_Wurst schrieb:

    Dieses C++ macht mich echt zu schaffen. (bin eher ein C-Programmierer)...

    Kann es vielleicht am Mix der beiden liegen ?
    In C++ heißen Funktionen nach dem Compile anders als in C ... wenn nun nach einem C-Compile eine Funktion in einem C++-Object (ohne extern "C") gesucht wird (oder anders herum), kommt es zu genau solchen unaufgelösten Referenzen.

    Die Funktionsnamen im Link-Output oben sehen ein wenig nach C-Object aus.

    Manche C/C++-Compiler entscheiden sich auch "automatisch" (z.B. aufgrund der Dateiendung) dafür, einen Quelltext in C und nicht in C++ zu kompilieren....

    Gruß,

    Simon2.


Anmelden zum Antworten