Когда я пытаюсь создать это, я получаю следующую ошибку компоновщика:
ErlDriver.obj: ошибка LNK2019: неразрешенный внешний символ _WinDynDriverCallbacks, указанный в функции __driver_output
erl_win_dyn_driver.h (включен в erl_driver.h)
typedef struct {
WDD_FTYPE(driver_output) *driver_output;
// a ton more of those
} TWinDynDriverCallbacks;
extern TWinDynDriverCallbacks WinDynDriverCallbacks;
#define driver_output (WinDynDriverCallbacks.driver_output)
Итак, как видите, WinDynDriverCallbacks объявлен defined.
Что же тогда может быть причиной ошибки компоновщика?
Существует тонкая разница между "объявлением" чего-либо и "определением" этого в C или C++. Когда вы объявляете его, он сообщает компилятору, что определенный символ будет определен где-то еще - это может позволить коду использовать этот символ без необходимости просмотра фактического определения. Вам все еще нужно определить символ где-то в коде, который связан, иначе вы получите сообщение об ошибке, которое видите.
Например, это объявление символа WinDynDriverCallbacks:
В вашем коде есть это объявление - оно позволяет коду, использующему символ, успешно компилироваться (но не связываться).
Вам нужно добавить определение где-то:
TWinDynDriverCallbacks WinDynDriverCallbacks;
Определение должно находиться где-то в файле исходного кода (обычно не в заголовочном файле). Это говорит компилятору выделить место в объектном коде для этого объекта и позволяет программе успешно компоноваться.
Ответ 2 · рейтинг 2 · Tyler McHenry
Нет, не определено (по крайней мере, в том, что вы процитировали). Это заявлено. Ключевое слово "extern" означает, что "определение этого символа появляется в другой единице компиляции (исходном файле)". Вы должны быть связаны с объектным файлом (или библиотекой), полученным в результате компиляции исходного файла, который определяет этот символ.
Ответ 3 · рейтинг 1 · Gary
У меня возникла очень похожая проблема при создании NIF в Windows. Неразрешенный внешний символ _WinDynNifCallbacks. Оказывается, это определяется макросом ERL_NIF_INIT, и в моем случае весь макрос нужно было заключить во внешний блок C.
то есть это не удалось
extern "C" ERL_NIF_INIT(...)
пока это удалось
extern "C"
{
ERL_NIF_INIT(...)
}
Я сильно подозреваю, что эта проблема связана с той же проблемой, но с макросом DRIVER_INIT для драйвера порта erlang.
Ответ 4 · jason
Driver_Init - это основной цикл, который объявляет "TWinDynDriverCallbacks WinDynDriverCallbacks;" но он правильно объявлен в многострочном определении для driver_init. Вам не нужно оборачивать его в extern "c".
поскольку эта тема поднималась около миллиона раз при попытке настроить мой драйвер порта erlang для barebone-систем, я скажу это здесь. Я работаю над книгой Джо Армстронга по программированию erlang, глава 12, методы взаимодействия. Использование erl5.9 и vs2010.
Код в книге содержал пропуск и ошибку в example1_lib.c. Хотя ошибка, скорее всего, связана с возрастом книги и изменениями версии erlang.
Необходимо установить (#define WIN32) в самом верху файла example1_lib.c, иначе erlang по умолчанию использует все параметры Linux.
Во-вторых, необходимо изменить (int bufflen) на (ErlDrvSizeT bufflen) в example_drv_output.