Domanda

Ho aperto un vecchio spazio di lavoro che è una libreria e il suo cablaggio di prova.Prima funzionava bene, ma ora non funziona più e anche le versioni precedenti del codice non funzionano con gli stessi errori.Ho provato a ricreare il progetto e anche questo causa gli stessi errori.Niente sembra fuori servizio nelle impostazioni del progetto e il codice generato funziona nell'app principale.

Ho eliminato la maggior parte dei file e ridotto al minimo indispensabile per generare l'errore.Sfortunatamente non posso pubblicare il progetto poiché viene utilizzato nel codice di produzione.

L'errore del linker LNK2001 che ricevo di solito significa che ho lasciato fuori una libreria o ho dimenticato di implementare una funzione virtuale.Tuttavia questo fa parte della libreria di modelli standard ed è anche un'intestazione.

Il codice elencato come presentante il problema in IOCompletionPort.obj in realtà non utilizza std::string direttamente, ma chiama una classe che fa: Comms::Exception accetta a std::string e il valore di GetLastError O WSAGetLastError.

La funzione menzionata nell'errore (GetMessage) è implementato, ma è una funzione virtuale quindi altre classi possono sovrascriverla se necessario.Tuttavia sembra che il compilatore l'abbia creata come versione Ansi, ma non riesco a trovare alcuna opzione nelle impostazioni che possa controllarla.Sospetto che potrebbe essere questo il problema, ma poiché ci sono pochissime opzioni per la libreria non ho modo di saperlo con certezza.Tuttavia, entrambi i progetti specificano _MBCS nelle opzioni del compilatore.

--------------------Configurazione:TestComms - Debug Win32-------------------- Collegamento in corso...Comms.lib (iocompleTionport.obj):errore LNK2001:simbolo esterno non risolto "pubblico:virtual class std::basic_string,class std::allocator > __thiscall Comms::Exception::GetMessageA(void)const " (?GetMessageA@ Exception@Comms@@UBE?AV?$basic_string@DU?$char_traits@D@std @@ v? $ Allocatore@d@2 @@ std @@ xz) debug/testcomms.exe:errore fatale LNK1120:1 Externals Externs Errore eseguendo Link.exe.

TestComms.exe - 2 errori, 0 avvisi

Eventuali suggerimenti?Ho perso gran parte della mattinata per questo e non voglio perdere anche gran parte del pomeriggio.

È stato utile?

Soluzione

Una possibilità risiede nel "name-mangling" di Win32 ANSI/Unicode, che trasforma il simbolo GetMessage in nessuno dei due GetMessageA O GetMessageW.Ci sono tre possibilità:

  1. Windows.h non è stato caricato, quindi GetMessage soggiorni GetMessage

  2. Windows.h è stato caricato con i simboli impostati per ANSI, quindi GetMessage diventa GetMessageA

  3. Windows.h è stato caricato con i simboli impostati per Unicode, quindi GetMessage diventa GetMessageW

Se hai compilato due file diversi in modi che attivano due scenari diversi, riceverai un errore del linker.Il messaggio di errore indica che il file Comms::Exception class era un'istanza di #2, sopra - forse è usata da qualche parte in cui windows.h non è stato caricato?

Altre cose che farei al posto tuo, solo per una questione di routine:

1) Assicurati che i miei percorsi di inclusione e libreria non contengano nulla che non mi aspetto.

2) Eseguire una "build clean" e quindi verificarla manualmente, eliminando eventuali file oggetto aggiuntivi se necessario.

3) Assicurarsi che non siano presenti percorsi hardcoded nelle istruzioni include che non significhino ciò che intendevano quando il progetto è stato originariamente ricostruito.

MODIFICARE:Litigare con la formattazione :(

Altri suggerimenti

@Curt:Penso che tu sia arrivato più vicino.Non l'ho provato, ma penso di aver dato la risposta nella mia domanda originale.

OttieniMessaggio è una definizione in Windows.h racchiusa in un blocco ifndef per passare da Ansi (GetMessageA) a Unicode (GetMessageW).

Presumendo che tu non abbia perso tempo con le impostazioni del progetto eliminando qualcosa che non dovresti avere (che è dove mi aspetto che siano dipendenze esterne come User32.lib):

Controlla strumenti | Opzioni | Directory | Biblioteche (passando dalla memoria qui) e assicurati che non ti manchi le directory Lib di varietà comuni (di nuovo, senza VC6 di fronte a me, non posso dirti cosa sono)

Questo è un problema generale relativo al modo in cui Microsoft ha gestito il confronto ANSI vs.API Unicode.Poiché sono tutti (o praticamente tutti) eseguiti definendo macro per i nomi delle funzioni che si risolvono nelle versioni "A" o "W" dei nomi delle funzioni, non è possibile avere in modo sicuro un identificatore nel proprio spazio dei nomi/classe/struct/enum/ funzione che corrisponde a un nome API di Windows.

Le macro windows.h prevalgono su tutti gli altri spazi dei nomi.

windows.h è dichiarato nella parte superiore di IOCompletionPort.h come inclusione: ero stufo di vedere 7 righe solo per includere 1 file, quindi l'ho racchiuso in un file e lo ho incluso stesso.Contiene anche alcune #define aggiuntive (ad esempio ULONG_PTR) poiché la nostra app principale non verrà compilata con Platform SDK installato :-(

  1. Ciò è confermato.Niente è fuori posto.
  2. L'ho fatto: ho cancellato le directory di build
  3. Non utilizzo mai percorsi codificati.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top