Нарушение прав доступа к LibVLC

Я пытаюсь настроить ведение журнала в LibVLC и сталкиваюсь с некоторыми проблемами.

Я использую функцию libvlc_log_set_file, вот документы: Журналирование LibVLC документы

Вот код, который у меня есть сейчас:

//header
private:
    FILE * logFile;

//source
logFile = fopen(path.c_str(), "w");
if(logFile != NULL)
{
    libvlc_log_set_file(_libvlc_instance, logFile);
}

В строке libvlc_log_set_file я получаю эту ошибку: «Необработанное исключение по адресу 0x77559E33 (ntdll.dll) в nw.exe: 0xC0000005: место записи нарушения прав доступа 0x00000014».

Я могу открыть и записать файл с fputs() просто отлично.

Я использую NW.js с компиляцией WebChimera.js в 32-разрядную версию с Visual Studio 2013 на 64-разрядной машине с Windows 7.

Любые идеи?


person cascade256    schedule 10.07.2015    source источник
comment
_libvlc_instance в порядке?   -  person Karoly Horvath    schedule 10.07.2015
comment
Я так думаю, это не нулевой указатель, и он может воспроизводить видео и все еще иметь проблему.   -  person cascade256    schedule 11.07.2015


Ответы (1)


У меня была именно эта проблема сегодня. Мне не удалось решить эту проблему с помощью libvlc_log_set_file. Вместо этого я решил использовать libvlc_log_set для настройки обратного вызова и использовать этот метод для записи в файл журнала. Вот пример, он показывает, что нужно сделать. Я не рекомендую глобальный указатель файла, он предназначен только для этого быстрого примера.

Примечание. logpath — это константа char*, содержащая путь к файлу журнала. Кроме того, вы, вероятно, захотите использовать flockfile, чтобы сделать этот поток безопасным. Вы также можете добавить туда оператор switch для обработки параметров уровня для LIBVLC_NOTICE, LIBVLC_ERROR, LIBVLC_WARNING и LIBVLC_DEBUG, чтобы придать логированию некоторую степень детализации.

bool g_loggingEnabled = true;
FILE* g_logfp = nullptr;

void logcb(void *data, int level, const libvlc_log_t *ctx, const char *fmt, va_list args)
{
    if (!g_loggingEnabled) return;

    if (g_logfp == nullptr)
    {
        errno_t err = fopen_s(&g_logfp, logpath, "w");

        if (err != 0)
        {
            g_loggingEnabled = false;
            return;
        }
    }

    vfprintf(g_logfp, fmt, args);
}

Приложение: В Windows вместо этого вы можете использовать CreateFile с установленным флагом FILE_SHARE_READ и использовать WriteFile, чтобы внешние текстовые редакторы могли просматривать файл во время регистрации в режиме реального времени. Если вы это сделаете, загляните в vsprintf_s вместо vfprintf, чтобы заполнить символьный буфер, который вы затем передадите WriteFile в методе logcb.

person Nelson Rush    schedule 14.07.2015
comment
Спасибо! Это прекрасно работает. Советы по его реализации приветствуются. - person cascade256; 16.07.2015
comment
Также стоит отметить, что в VS 2013 %zd и %zu не поддерживают спецификаторы vsnprintf_s и т. д., но libvlc использует их для передачи вам целочисленных значений. Я спросил об этом Жана Батиста, главу VLC, и он сказал, что VS 2015 должен обрабатывать эти спецификаторы. Я еще не пробовал это, на работе здесь у меня есть VS 2013. Вместо этого я искал и заменял %zd и %zu на %Id и %Iu, но я использую возможности String^, такие как .Replace in C++/CLI, а затем marshal_context как const char* fmt, что делает это безболезненным. Я не обязательно рекомендую этот подход, но скоро мне нужно будет продемонстрировать его. - person Nelson Rush; 18.07.2015
comment
Я нашел достойный способ обработки уровней журнала без переключателя, поместив следующую строку в начало метода после строки с включенным ведением журнала. Где g_loggingLevel — это LIBVLC_DEBUG или любой другой уровень, который вы хотите использовать. Это работает, потому что каждый уровень численно выше другого в перечислении. Примечание. Это может сломаться, если они когда-либо изменят значения, чтобы они не были последовательными, но это маловероятно. if (g_loggingLevel > level) return; - person Nelson Rush; 18.07.2015
comment
К сожалению, мне пришлось перейти с VS2015 на VS2013 для совместимости с NW.js, так что спасибо за внимание к форматированию. В других библиотеках, которые я использовал, уровни ведения журнала просто сохраняются как «int», поэтому я предположил, что это то же самое. Рад, что все же работает! - person cascade256; 19.07.2015
comment
Когда вы передаете аргументы инициализации методу libvlc_new, вы можете добавить -vvv, чтобы получить больше подробностей. Количество v, которое вы предоставляете, определяет, насколько мало или насколько больше информации вы получите. Это полезно, если вы изо всех сил пытаетесь понять, что происходит в libvlc или его плагинах. - person Nelson Rush; 20.07.2015