Неразрешенный внешний символ — компоновщик VC++

Я использую WDM для создания простого драйвера. (У меня установлена ​​последняя версия WDK, а также последняя версия Visual Studio 2017).

Проблема в том, что когда дело доходит до сборки решения, оно просто не проходит компоновщик и возвращает ошибку 2019 (нажмите здесь, чтобы узнать об этом подробнее, если вы не знакомы с ошибкой), и там написано, что _DriverEntry@8 является неразрешенным внешним символ, указанный в функции _GsDriverEntry@8, а файл называется BufferOverflowFastFailK.lib.

Вот как я написал подпись своей функции: NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, _In_ PUNICODE_STRING RegistryPath)

Кто-нибудь знает, как это исправить?

РЕДАКТИРОВАТЬ: Вот мой код:

#include "ntddk.h"

UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\deviceone");
UNICODE_STRING SymLinkName = RTL_CONSTANT_STRING(L"\\??\\deviceonelink");
PDEVICE_OBJECT DeviceObject = NULL;

void Unload(PDRIVER_OBJECT DriverObject) {
    IoDeleteSymbolicLink(&SymLinkName);
    IoDeleteDevice(DeviceObject);
    KdPrint(("Driver unloaded"));
}

NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, _In_ PUNICODE_STRING RegistryPath) {
    NTSTATUS status;

    DriverObject->DriverUnload = Unload;

    status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);

    if (!NT_SUCCESS(status)) {
        KdPrint(("Couldn't create device"));
        return status;
    }

    status = IoCreateSymbolicLink(&SymLinkName, &DeviceName);

    if (!NT_SUCCESS(status)) {
        KdPrint(("Failed to create symbolic link"));
        IoDeleteDevice(DeviceObject);
        return status;
    }

    KdPrint(("Driver has been loaded"));

    return status;
}

person Eyal B    schedule 21.12.2018    source источник
comment
Я пытался добавить bufferoverflowfailk.lib в качестве дополнительной зависимости в параметрах компоновщика в свойствах конфигурации, а также в прагме, но все равно безуспешно...   -  person Eyal B    schedule 21.12.2018
comment
Недостаточно деталей в вопросе, чтобы ответить на вопрос. Вы можете проверить объект вывода компиляции, который вы связываете с dumpbin /symbols, чтобы проверить, чем он отличается от ожидаемого символа.   -  person PeterT    schedule 21.12.2018
comment
Вы должны не только объявить, но и определить функцию, вы это понимаете, верно?   -  person PeterT    schedule 21.12.2018
comment
Да, я определил функцию.   -  person Eyal B    schedule 21.12.2018
comment
Правильно, но это не модуль компиляции, в котором вы определили DriverEntry, я предлагал вам выгрузить артефакт компиляции из файла cpp, который содержит функцию DriverEntry.   -  person PeterT    schedule 21.12.2018
comment
Обратите внимание на UNDEF. Не могли бы вы показать весь свой код? Возможно, есть какие-то проблемы с косяком...   -  person Igor R.    schedule 21.12.2018
comment
@PeterT BufferOverflowFailK.lib: 00E 00000000 UNDEF notype () Внешний | DriverEntry@8 00F 00000000 SECT4 notype () Внешний | _GsDriverEntry@8 вот что я нашел в своем файле: 023 00000000 SECT8 notype () Внешний | ?DriverEntry@@YGJPAU_DRIVER_OBJECT@@PAU_UNICODE_STRING@@@Z (long __stdcall DriverEntry(struct _DRIVER_OBJECT *,struct _UNICODE_STRING *)) 026 00000000 SECTC notype Static | __guard_fid?DriverEntry@@YGJPAU_DRIVER_OBJECT@@PAU_UNICODE_STRING@@@Z   -  person Eyal B    schedule 21.12.2018
comment
правильно, так что он экспортирует соглашение о вызовах C++ и пытается импортировать C, вам не хватает extern "C" впереди   -  person PeterT    schedule 21.12.2018
comment
@PeterT это искажение имени (декорарион символов), а не соглашения о вызовах.   -  person Igor R.    schedule 21.12.2018
comment
@ИгорьР. Вы правы, ошибка компоновщика произошла из-за разницы в искажении имен. Но я думаю, что extern C также влияет на соглашение о вызовах в дополнение к этому.   -  person PeterT    schedule 21.12.2018


Ответы (1)


если вы работаете с драйверами, лучше всего использовать их в заголовках:

#ifdef __cplusplus
extern "C" {
#endif

NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, _In_ PUNICODE_STRING RegistryPath);

#ifdef __cplusplus
}
#endif

или просто extern "C" NTSTATUS DriverEntry(_In_ struct _DRIVER_OBJECT *DriverObject, _In_ PUNICODE_STRING RegistryPath);, если это единственная функция, которую вам нужно экспортировать с соглашением о вызовах C и оформлением символов.

person PeterT    schedule 21.12.2018
comment
Это решило мою проблему. Большое спасибо! - person Eyal B; 21.12.2018
comment
В состав WinSDK входит утилита командной строки, которая называется DUMPBIN.EXE. Одна вещь, для которой это полезно, - это подтверждение того, что экспортируемые функции «экспортируют» вашу DLL — это то, чем они должны быть. Проверьте DUMPBIN /EXPORTS - person Scott Smith; 04.10.2020