Переопределить функции файла библиотеки c?

Я работаю над игрой, и одним из требований лицензионного соглашения на звуковые ресурсы, которые я использую, является их распространение таким образом, чтобы они были недоступны для конечного пользователя. Итак, я подумываю объединить их в плоский файл, зашифровать их или что-то в этом роде. Проблема в том, что звуковая библиотека, которую я использую (Hekkus Sound System), принимает только путь к файлу char * и обрабатывает чтение файлов внутри. Итак, если я продолжу использовать его, мне придется переопределить функции файла c stdio для обработки шифрования или того, что я решу сделать. Это кажется выполнимым, но меня это беспокоит. Глядя в Интернет, я вижу, как люди сталкиваются со странными неприятными проблемами, делая это на платформах, которые меня интересуют (Win32, Android и iOS).

Есть ли кроссплатформенная библиотека, которая позаботится об этом? Вы бы порекомендовали лучший подход?


person Vigabrand    schedule 03.09.2013    source источник
comment
Не могли бы вы их декодировать и записать в недекодированном виде в файл / tmp, а затем вызвать открытие и затем отсоединить их сразу после открытия? Дескриптор файла внутри Hekkus останется действующим после открытия. (править: идея с RAM-диском ниже кажется лучше)   -  person Charlie Burns    schedule 03.09.2013
comment
Определите недоступное. Если вы проигрываете звук в системе пользователя, мне это кажется довольно доступным. Во всяком случае, что касается звуковой системы Hekkus - на сайте автора написано, что он предлагает источники всем, кому интересно. Так что проще всего было бы получить исходный код и исправить его. Как ни странно, эта звуковая библиотека не абстрагируется от способа ввода в нее данных.   -  person n0rd    schedule 03.09.2013
comment
Пожалуйста, не переопределяйте зарезервированный идентификатор в C, это вызовет неопределенное поведение. В проекте стандарта C99 говорится (Приложение J, раздел J.2): Поведение не определено в следующих случаях: [...] Программа пытается объявить саму библиотечную функцию, а не через стандартный заголовок, но объявление не имеет внешней связи (7.1.2). Программа объявляет или определяет зарезервированный идентификатор, кроме разрешенного в 7.1.4 (7.1.3).   -  person Lorenzo Donati -- Codidact.com    schedule 03.09.2013
comment
какой набор инструментов вы используете?   -  person secmask    schedule 03.09.2013
comment
@charlie burns. Это может сработать, но будет медленнее, а время загрузки уже является проблемой. Является ли такое поведение подсчета ссылок дескрипторами файлов частью стандарта (переносимого)?   -  person Vigabrand    schedule 03.09.2013
comment
@ n0rd они не хотят, чтобы конечные пользователи брали файлы и использовали их сами. Спасибо, на сайте это совсем не попало, попробую.   -  person Vigabrand    schedule 03.09.2013
comment
@secmask сейчас просто msvc, я еще не начал портировать.   -  person Vigabrand    schedule 03.09.2013
comment
@LorenzoDonati это не переопределит зарезервированный идентификатор, а скорее изменит связь времени выполнения через специфичные для ОС вызовы   -  person Vigabrand    schedule 03.09.2013
comment
Я думаю, вы можете положиться на это поведение открытия / отключения в unix. Я понятия не имею об окнах.   -  person Charlie Burns    schedule 03.09.2013
comment
Извините, я неправильно понял ваше предложение. Мне придется переопределить функции файла c stdio [...]. В любом случае, изменяя связь [...], вы имеете в виду, что будете связывать (возможно, динамически) с другой средой выполнения? Если да, уверены ли вы, что изменение базовой реализации файловых функций не вызывает неопределенного поведения?   -  person Lorenzo Donati -- Codidact.com    schedule 03.09.2013


Ответы (6)


Есть ли у вас возможность использовать именованный канал вместо обычного файла? Если это так, вы можете представить канал звуковой библиотеке как файл для чтения, и вы можете расшифровать свои данные и записать их в канал, без проблем. (См. Руководство по Beej для объяснение именованных каналов.)

person This isn't my real name    schedule 03.09.2013
comment
Я не понимаю. Кажется, вы говорите, что вместо передачи звуковых данных в библиотеку вы должны передать ей имя файла. В этом случае решением может быть именованный канал, также называемый FIFO. Именованный канал представляет собой файл в файловой системе, так что все, что открывает файл для чтения, оказывается на принимающей стороне вашего канала вместо чтения файла на диске. Таким образом, ваша программа может создать именованный канал, передать имя файла канала в звуковую библиотеку и записать дешифрованные аудиоданные для записи в конец канала. - person This isn't my real name; 03.09.2013
comment
Именованный канал в Unix - это файл, который можно открыть как обычный файл, поэтому его имя - обычный символ 'char *', и у аудиобиблиотеки не должно быть проблем с чтением из него. Однако он должен быть создан с помощью функции mkfifo, например, в другом потоке вашей программы, и записан в, иначе fopen заблокируется (см. stackoverflow.com/questions/580013/ < / а>) - person SirDarius; 03.09.2013
comment
Независимая платформа именованных каналов? Это также означает, что вы знаете, как библиотека открывает файл на разных платформах. - person Martin Schlott; 03.09.2013
comment
К сожалению, это похоже только на Linux? - person Vigabrand; 03.09.2013
comment
Вернее, в Windows есть такая возможность, но, к сожалению, она несовместима с fopen. - person Vigabrand; 03.09.2013
comment
Вы указали Android и iOS в качестве платформ, которые вас интересуют, и Google, похоже, указывает, что обе эти платформы поддерживают POSIX. Windows, которую вы не указали в качестве интересующей платформы, хорошо известно, что она плохо поддерживает POSIX (если вообще поддерживает), поэтому нет, там это не сработает. - person This isn't my real name; 03.09.2013
comment
Хотя, согласно ответам @Martin Schlott, окна имеют ту же функциональность (конечно, не POSIX) и совместимы с fopen, так что это может работать в конце концов ... - person Vigabrand; 04.09.2013
comment
Я думаю, что это сработает, поэтому я отмечу как отвеченный, если не узнаю иначе, ty - person Vigabrand; 04.09.2013
comment
Я сделал это сам с помощью консольного приложения, ожидая пути к файлу. Я дал ему именованный канал, созданный с помощью CreateFile, и он отлично работал. Тем не менее, поведение между Windows и системой на основе POSIX различается, и это не оставляет вам другого выбора, кроме различия между MS и остальным миром. - person Martin Schlott; 04.09.2013

Переопределение stdio таким образом, чтобы библиотека, которую вы не знаете, как она работает, точно работала так, как разработчик не задумывал, для меня не выглядит правильным подходом, поскольку это не совсем просто. Реализация ramdrive требует так много усилий, что я рекомендую поискать другую аудио библиотеку.

Я обнаружил, что Hekkus Sound System была создана одним человеком и последний раз обновлялась в 2012 году. Я бы не стал полагаться на библиотеку. над этим работает только один человек, не делясь источниками.

Мой совет: потратьте свое время на поиск подходящей звуковой библиотеки, а не на поиск подозрительного решения для этой.

person Martin Schlott    schedule 03.09.2013
comment
Я слышу тебя. Но было бы прискорбно, если бы до этого доехало, поскольку помимо этой проблемы Hekkus зарекомендовал себя как полнофункциональная и простая в использовании библиотека очень высокого качества, несмотря на то, что это работа одного человека, и кроссплатформенность для платформ, которые я использую. заботиться. Почему вы говорите, что переопределить stdio сложно? Кажется, что добавление тонкого слоя, выполняющего простую расшифровку, не должно быть слишком сложным, если я получаю фактическую работу, переопределяющую работу. - person Vigabrand; 03.09.2013
comment
Это может быть, и это, конечно, полностью ваше решение. Честно говоря, я не знаю способа переопределить stdio независимым от платформы способом. Например, решение для Windows - создать именованный канал, вы можете построить путь к именованному каналу, который может быть открыт любой функцией файла stdio. Есть аналогичный механизм для Linux, но я не знаю, является ли он таким же для любой другой платформы, такой как iPhone или Android. Для Windows, создающей именованный канал, вы можете использовать CreateFile API Windows. Насколько мне известно, нет доступной библиотеки именованных каналов, независимой от платформы (пока). - person Martin Schlott; 03.09.2013
comment
Путем переопределения stdio я имел в виду переопределение fopen / fread / etc через dlsym на * nix и эквивалент (хм, есть ли он?) В Windows - person Vigabrand; 04.09.2013
comment
Но да, возможно, вы правы, что вам нужна другая библиотека - person Vigabrand; 04.09.2013

Одна из возможностей - использовать зашифрованную файловую систему с обратной связью (Google для Дополнительные ресурсы).

Это работает так: вы помещаете свои ресурсы в зашифрованную файловую систему, которая на самом деле находится в простом файле. Эта файловая система монтируется где-нибудь как устройство обратной связи. Пароль должен быть предоставлен во время присоединения / монтирования. После подключения все файлы становятся доступными для вашего программного обеспечения как обычные файлы. Но в остальном файлы зашифрованы и недоступны.

person Ziffusion    schedule 03.09.2013
comment
Кажется, это концепция только для Linux? - person Vigabrand; 03.09.2013
comment
В большинстве ОС * nix (включая MacOS), похоже, есть en.wikipedia.org/wiki/Loop_device. Кроме того, поскольку Android является производным от Linux, он тоже должен быть в нем. - person Ziffusion; 03.09.2013
comment
Я также буду выпускать для Windows. - person Vigabrand; 03.09.2013
comment
Я уверен, ты сможешь что-нибудь найти. sourceforge.net/projects/freeotfe.mirror - person Ziffusion; 03.09.2013

Это зависит от компилятора и не является гарантированной функцией, но многие из них позволяют вставлять файлы / ресурсы непосредственно в exe и читать их в коде, как если бы с диска. Таким образом вы можете встроить свои звуковые файлы. Однако это значительно увеличит размер вашего exe.

person Neil Kirk    schedule 03.09.2013
comment
Однако это не работает прозрачно, поэтому библиотека не сможет открыть эти файлы. - person Vigabrand; 03.09.2013
comment
@Vigabrand Почему бы и нет? Просто загрузите их в массив байтов. - person Neil Kirk; 04.09.2013
comment
символ * относится к имени файла в Hekkus API. - person Vigabrand; 04.09.2013
comment
@Vigabrand Мне не удалось найти документацию по Hekkus API, чтобы узнать, есть ли альтернативные способы. - person Neil Kirk; 04.09.2013

Другой подход на основе UNIX:

Переменная среды LD_PRELOAD может использоваться для переопределения любой разделяемой библиотеки, с которой был связан исполняемый файл. Все символы, экспортируемые библиотекой, упомянутой в LD_PRELOAD, разрешаются в эту библиотеку, включая вызовы функций libc, таких как open, read и close. Используя libdl, библиотека обертывания также может обращаться к исходной реализации.

Итак, все, что вам нужно сделать, это запустить процесс, который использует звуковую систему Hekkus в среде, в которой установлен LD_PRELOAD соответствующим образом, и вы можете делать все, что захотите, с файлом, который он читает.

Обратите внимание, однако, что нет абсолютно никакого способа сохранить данные недоступными для пользователя: сам факт, что он должен слышать их, означает, что он должен иметь доступ. Даже если все программное обеспечение в цепочке будет использовать шифрование, а ваш пользователь не захочет взламывать оборудование, было бы не так уж сложно соединить гнездо аудиовыхода с гнездом аудиовхода, не так ли? И нельзя же запретить пользователю пользоваться наушниками, не так ли? И, конечно же, ядро ​​может видеть весь аудиовыход в незашифрованном виде и может отправить копию в другое место ...

person cmaster - reinstate monica    schedule 03.09.2013
comment
Похоже, интересный вариант, хотя я тоже должен поддерживать окна. Что касается вашего второго момента, звуки не воспроизводятся по отдельности, есть музыка и несколько звуков, поэтому это было бы не очень полезно. - person Vigabrand; 04.09.2013
comment
Хотя я никогда не делал ничего подобного, я могу придумать методы обратного проектирования исходных звуков, и они не совсем сложные ... Но, конечно, если ваш источник музыки доволен зашифрованными исходными файлами и также доволен возможностью извлечения музыки в любом случае, вроде бы проблем нет. Только убедитесь, что он не сможет подать на вас в суд, когда музыкальные файлы появляются в Интернете ... - person cmaster - reinstate monica; 04.09.2013

Решением вашей проблемы будет рамдиск. http://en.wikipedia.org/wiki/RAM_drive Использование фрагмента памяти в оперативной памяти в качестве если бы это был диск. Для этого тоже есть программное обеспечение. Кэширование баз данных в оперативной памяти становится популярным.

И это предотвращает появление файла на диске, что сделало бы его доступным для пользователя.

person Peter Trypsteen    schedule 03.09.2013
comment
На Android? IPad? - person This isn't my real name; 03.09.2013
comment
Мне бы очень не хотелось, чтобы игра или приложение добавляли новый диск в систему во время работы. Кроме того, я не знаю, есть ли портативное решение, и для этого, вероятно, потребуются права root / admin. - person interjay; 03.09.2013
comment
Вопрос показывает, что спрашивающий больше на новичке в разработке. Внедрение ramdisk не похоже на правильный совет. Дополнительно я не знаю рамдиска, который не зависит от платформы. - person Martin Schlott; 03.09.2013
comment
@Martin Schlott Hrm не обязательно LOL - person Vigabrand; 03.09.2013
comment
Не хотел тебя обидеть. - person Martin Schlott; 03.09.2013