Синтаксис LNK2019, LPCTSTR и C ++ в целом

0

Позвольте мне изложить этот вопрос двумя замечаниями:
1) Я разработчик С#, поэтому у меня нет большой практики, связанной с ошибками компоновщика в C++, и какой-то стандартный синтаксис C++ мне незнакомо. Я подозреваю, что это будет непростым вопросом для гуру C++.
2) Я не уверен, как задать этот вопрос таким образом, который будет иметь отношение к массам, но я открыт для предложений/исправлений сообщества. Проблема с ошибками lnk2019 состоит в том, что она кажется довольно индивидуализированной относительно того, что на самом деле проблема. В MSDN есть статья, которая имеет дело с ошибкой, и Qaru уже имеет множество вопросов с этим тегом, и все же я все еще не могу решить свою проблему.

Подробнее...
Мне было предоставлено старое (VS2005) C++ решение с 42 проектами, и его попросили попытаться его построить. Проделав довольно много сплетен, я получил всего три проекта, которые не будут строить. Я хотел бы сосредоточиться только на одном из них, потому что я думаю, что если мы сможем понять, что один из них, я могу сделать то же самое для других 2 проектов, чтобы исправить их.

Начните с ошибки. Как вы можете видеть, проект, о котором идет речь, называется "HttpWire".

Удаление промежуточных и выходных файлов для проекта "Http Wire", настройка "Release | x64"
Компиляция...
HttpWire.cpp
Компилирование ресурсов...
Образцы...
Создание библиотеки Release\AMD64\HttpWire.lib и объект Release\AMD64\HttpWire.exp
HttpWire.obj: ошибка LNK2019: неразрешенный внешний символ "public: __cdecl THttpWire :: THttpWire (char const *)" (?? 0THttpWire @@QEAA @PEBD @Z), на который ссылается функция CreateConnectionWire Release\AMD64\HttpWire.dll: фатальная ошибка LNK1120: 1 нерешенные внешние

Похоже, что компоновщик расстроен, потому что функция "CreateConnectionWire" вызывает "THttpWire", но по какой-то причине компоновщик не может ее найти. В проекте есть только 1 файл.cpp(HttpWire.cpp), и вот он:

#include "THttpWire.h"

BOOL WINAPI DllMain(HINSTANCE hDllInst, DWORD reason, LPVOID reserved)
{
    return TRUE;
}

__declspec(dllexport) TConnectionWire *CreateConnectionWire(LPCTSTR connectionString)
{
    return new THttpWire(connectionString);
}

__declspec(dllexport) void DeleteConnectionWire(TConnectionWire *connectionWire)
{
    delete connectionWire;
}

Файл #include, "THttpWire.h" живет в другом проекте под названием "AirTime Core". Он включает в себя несколько других вещей, а затем имеет следующее:

class THttpWire : public TConnectionWire
{
public:
    THttpWire(LPCTSTR connectionString);
    virtual ~THttpWire();

... (lots of other stuff) ...
}

И наконец, у нас есть THttpWire.cpp:

#include "THttpWire.h"
...
THttpWire::THttpWire(LPCTSTR connectionString) :
TConnectionWire(connectionString),
hWinHttp(NULL), hSession(NULL), hRequest(NULL),
opTimedOut(FALSE), asyncError(0),
headers(NULL), headersOffset(0), headersLength(0),
availData(0)
{
    requestSent = new TSyncEvent(TRUE);
    updateToString();
}

Этот синтаксис для меня немного странный... что мы здесь делаем? Я имею в виду, что я понимаю, что это конструктор, и поскольку THttpWIre, похоже, наследуется от TConnectionWire (в соответствии с.h), тогда ": TConnectionWire (connectionString)" имеет смысл (я предполагаю, что это похоже на добавление С#): base() "для конструкторов объектов, которые наследуются от других объектов), но тогда, что это все остальное между этим и открывающей скобкой (обратите внимание, что TConnectionWire не наследует ни от чего другого)?

ТАК...
После нескольких поисков в MSDN и SO я узнал следующее (пожалуйста, поправьте меня, если я ошибаюсь)

  1. CreateConnectionWire предваряется __declspec (dllexport), который просто делает его доступным для других проектов, потребляющих этот.dll (как описано здесь)
  2. LPCTSTR является константой char * (см. MSDN). Обратите внимание, что мои проекты заданы с помощью "Обработать wchar_t как встроенный тип: Нет (/Zc: wchar_t-)" на страницах свойств. (см. нижнюю часть этой статьи, а также эту статью)

Прямо сейчас, мое основное подозрение связано с LPCTSTR. Возможно, в обоих проектах они не определены одинаково, что даст разные сигнатуры методов... но я не знаю, как это проверить или исправить, если это так. Или, возможно, "/Zc: wchar_t-" вещь влияет на него неблагоприятно?
Мое следующее подозрение состоит в том, что в цепочке методов, перечисленных в конструкторе, есть что-то (с синтаксисом, который я не понимаю), который вызывает какую-то проблему и вообще не делает конструктор "THttpWire" недоступным.
Как вы думаете? Я был бы рад поделиться любыми другими битами, которые, по вашему мнению, были бы полезными.


Другая информация, которая может быть или не быть полезной (я позволю вам решить)

  1. Когда я впервые начал работать с этим проектом, осталось несколько файлов.lib и.h, и мне пришлось искать их, чтобы найти их (примерами были opends60.lib, mssoap30.lib, WinLUA.h и т.д.). Вполне возможно, что у меня нет той же версии, из которой первоначально было построено решение.
  2. Все проекты были построены с использованием "_WIN32_WINNT = 0x0400", что означает, что он должен был быть построен против Windows 2000 SDK (см. MSDN). Я нашел кое-что, что я считал Win 2000 SDK (самый старый из них здесь, но когда я ссылаюсь на это, у меня появляется больше ошибок. Вместо этого я привязываюсь к версии SDK 6.1. ОДНАКО, это приводит к тому, что WinHttp не компиляция, потому что "SOCKADDR_STORAGE" не определен ни для чего "_WIN32_WINNT <0x0501" (Windows XP). THUS, я переопределил "_WIN32_WINNT = 0x0501" для всех проектов, которые, как представляется, связаны с HttpWire. Возможно, я пропустил один или два.
  • 0
    Я предполагаю, что определение LPCTSTR изменилось с char * на wchar_t * . Это настраивается через определенную константу.
  • 0
    Как / где я буду искать это?
Показать ещё 5 комментариев
Теги:
visual-c++
lnk2019

1 ответ

2
Лучший ответ

В проекте всего 1 файл.cpp(HttpWire.cpp)

Ну, это проблема, потому что вам явно нужно больше 1. Вам также нужен THttpWire.cpp, так как он содержит код конструктора. Тот, который линкер не может найти.

Сохраняйте модель сборки C++, она сильно отличается от С#. Файлы исходного кода отдельно компилируются. И тогда компоновщик склеивает все биты кода вместе, чтобы сделать программу. Эти биты могут быть получены из файла.obj, созданного из файла.cpp. Или они могут поступать из файла.lib, "контейнера" бит кода.

Это вероятное объяснение, так как вы упомянули проект AirTime Core. Project + Properties, Linker, Input, Additional Dependencies. Вам нужно добавить выход проекта "AirTime Core", независимо от того, что он назвал.

  • 0
    Хорошо, поэтому AirTimeCore выводит файл .lib, но, как оказалось, HttpWire неправильно связывался с ним. Спасибо за помощь!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню