C ++ char * относительный путь к файлу? (Qt)

Я пытаюсь воспроизвести аудиофайл .mod в исполняемом файле. Я использую сторонний BASSMOD .dll. Я могу получить аудиофайл для воспроизведения, когда я указываю полный путь к файлу, но не могу воспроизвести его при указании относительного пути. Вот несколько фрагментов.

main.cpp

#include <QCoreApplication>
#include "bassmod.h"
// define file location
const char* file = "C:/Users/Downloads/test4/console/music.mod";

void startMusic() {
BASSMOD_Init(-1, 44100, 0);
BASSMOD_MusicLoad(FALSE,(void*)file,0,0,BASS_MUSIC_RAMPS);
BASSMOD_MusicPlayEx(0,-1,TRUE);
}

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
startMusic();
return a.exec();
}

bassmod.h (соответствующий фрагмент)

BOOL BASSDEF(BASSMOD_MusicLoad)(BOOL mem, void* file, DWORD offset, DWORD length, DWORD flags);

Я обеспокоен функцией BASSMOD_MusicLoad, Поскольку этот проект стоит, файл .mod будет воспроизводиться без проблем. Однако когда я пытаюсь изменить абсолютный путь файла .mod на относительный путь («music.mod»), файл не воспроизводится. Это почему? У меня есть файл .mod в том же каталоге, что и исполняемый файл, а также в каталоге, содержащем файл .pro — это не проблема.

Также, возможно, я что-то упускаю из-за того, как файлы открываются в C ++. Похоже, MusicLoad функция требует что второй параметр имеет тип void*, Я уверен, что есть много разных вещей, которые я мог бы сделать лучше здесь. В идеале я бы хотел иметь возможность file сохраните относительный путь к файлу .mod и сделайте так, чтобы мне не приходилось жестко кодировать абсолютный путь. В идеальном мире я хотел бы поставить file с путем к файлу .mod в моем resources.qrc, но тогда мне придется использовать QFileЯ считаю, что это не сработает, потому что мне нужно, чтобы тип был void *.

Любая помощь для начинающего будет высоко ценится.


РЕДАКТИРОВАТЬ 01: Спасибо за вашу помощь! Я получил его на работу (используя относительный путь к файлу, по крайней мере). Есть два способа сделать это. Вот что я сделал и как я это проверял:

В первом случае предполагается, что BASSMOD (или какая-либо внешняя DLL, которую вы используете) не обрабатывает относительные пути.

const char* file = "C:/debug/music.mod"; // same dir as .exe
QFileInfo info("music.mod");
QString path = info.absoluteFilePath();
const string& tmp = path.toStdString();
const char* raw = tmp.data();

Это тестовые задания, которые я настроил. Когда я бегу BASSMOD_MusicLoad(FALSE,(void*)file,0,0,BASS_MUSIC_RAMPS);работает как положено. Вот тогда я жестко закодировал полный абсолютный путь.

Когда я побежал BASSMOD_MusicLoad(FALSE,(void*)raw,0,0,BASS_MUSIC_RAMPS);не сработало. Поэтому я решил распечатать значения для всего, чтобы увидеть, где это происходит:

 cout << "Qstring path: ";
qDebug() << path;
cout << "string& tmp: ";
cout << tmp << endl;
cout << "raw: ";
cout << raw << endl;
cout << "full char* file: ";
cout << file;
startMusic();

…возвращает это:

Qstring path:
"C:/myApp/build-Debug/music.mod"string& tmp:
C:/myApp/build-Debug/music.mod
raw:
C:/myApp/build-Debug/music.mod
full char* file:
C:/myApp/build-Debug/debug/music.mod

Обратите внимание на разницу? Когда я жестко запрограммировал полный путь к файлу, я обнаружил, что (благодаря @FrankOsterfeld и @JasonC) текущий рабочий каталог фактически не находится там, где находятся файлы .exe (/ debug) или .pro. На самом деле он был в том же каталоге, что и Makefile.

Так что я просто изменил это на: QFileInfo info("./debug/x.m"); и это сработало.

Несмотря на то, что проблема заключалась в том, что я не знал, где находится текущий рабочий каталог, решения @Radek, @SaZ и @JasonC помогли найти другой способ решения этой проблемы (плюс он показал мне, как получить рабочие каталоги и преобразовать их). между типами). Это хороший справочник для людей, которые хотят использовать QFileInfo, чтобы определить, где вы на самом деле находитесь в файловой системе. Я бы использовал это решение, если бы dll, который я использовал, не обрабатывал относительные пути хорошо. Тем не мение…

Я задавался вопросом, смогу ли я применить то же решение к моему исходному коду (без использования QFileInfo, преобразования типов и т. Д.). Я предположил, что BASSMOD не обрабатывает относительные пути из коробки. Я был неправ. Я изменил file переменная к const char* file = "./debug/x.m"; Это сработало!

Спасибо всем за помощь!

Тем не менее, я все еще хотел бы заставить это работать, используя music.mod из файла ресурсов Qt. Однако, основываясь на ответах, это не представляется возможным, если только используемая вами сторонняя библиотека не поддерживает систему ресурсов Qt.

2

Решение

У меня есть файл .mod в той же директории, что и исполняемый файл.

В Qt Creator исходным рабочим каталогом по умолчанию является каталог, в котором находится файл .pro, а не каталог, в котором находится .exe.

Либо поместите свой файл в этот каталог (тот, который, вероятно, содержит все исходные файлы и тому подобное, если вы использовали обычную настройку), либо измените каталог запуска на каталог, в котором находится файл .exe (в разделе «Выполнить»). Область настроек).

Хотя, исходя из вашего нового комментария ниже, я думаю, что проблема еще глубже … Я не могу сказать вам, почему BASS не нравится относительные имена файлов, но вы можете преобразовать относительный путь в абсолютный, прежде чем передать его BASS. Есть много способов сделать это; используя API Qt, вы можете:

#include <QFileInfo>

...
const char* file = "music.mod";  // Your relative path.
...

BASSMOD_MusicLoad(...,
(void*)QFileInfo(file).absoluteFilePath().toAscii().data(),
...);

В идеальном мире я хотел бы предоставить файлу путь к файлу .mod в моих ресурсах. Qrc

Вы не сможете этого сделать, потому что загрузка ресурсов из файлов .qrc — это вещь Qt, и BASS, по-видимому, не использует Qt для внутреннего использования (как, например, вы не можете открыть ресурс с помощью fopen), и не понимает, как загружать ресурсы, встроенные в Qt. Я не знаком с BASS, но беглый взгляд на эта документация показывает, что он также может воспроизводить данные из буфера в памяти. Поэтому одним из подходов будет использование Qt для загрузки ресурса в доступную память и передачи этого буфера.

4

Другие решения

В идеальном мире я хотел бы предоставить файлу путь к файлу .mod в моем resources.qrc, но тогда мне придется использовать QFile, я считаю, что он не будет работать, потому что мне нужен тип, чтобы быть пустым *.

Почему вы только верите? Прочитайте Qt Doc. Это будет работать. Не используйте класс QFile но QFileInfo,

QFileInfo info(:/resourcePrefix/name);
QString path = info.absoluteFilePath();
void* rawPtr = (void*)path.toStdString().c_str();
-1

По вопросам рекламы [email protected]