【发布时间】:2016-01-28 05:02:21
【问题描述】:
我正在尝试在可执行文件中播放 .mod 音频文件。我正在使用第 3 方 BASSMOD .dll。当我提供文件的完整路径时,我可以播放音频文件,但在提供相对路径时无法播放。这里有一些sn-ps。
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(相关sn-p)
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 文件的相对路径并让它以这种方式播放,这样我就不必硬编码绝对路径。在一个完美的世界中,我想在我的 resources.qrc 中为file 提供一个指向 .mod 文件的路径,但是我相信我必须使用QFile,因为我需要类型为 void*。
对初学者的任何帮助将不胜感激。
EDIT 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"; 它有效!
谢谢大家的帮助!
但是,我仍然希望使用来自 Qt 资源文件的 music.mod 来使其正常工作。不过,根据回复,除非您使用的第 3 方库支持 Qt 资源系统,否则这似乎是不可能的。
【问题讨论】:
-
BASSMOD_MusicLoad 返回什么错误码?
-
要做到这一点,我可以将
cout << BASSMOD_ErrorGetCode();放在BASSMOD_MusicLoad行下吗?当我这样做时,它只会将“2”返回到标准输出。编辑:没关系。我在头文件中找到了错误代码。 “2”是#define BASS_ERROR_FILEOPEN 2 // can't open the file -
所以它显然只是找不到文件。我想这与 BASSMOD 如何读取文件有关。由于它是一个编译后的 .dll,不幸的是,它有点像黑盒。
-
我不想问这个显而易见的问题,但只是为了解决这个问题,您的文件还存在吗?您是否可能在实验中不小心移动/重命名/删除了它?您确定您的“music.mod”拼写正确(没有逗号代替句点、其他常见的拼写错误等)吗?
-
您确定 BASSMOD_MusicLoad 是否考虑了当前工作目录? (您可以检查它的路径,例如 QDir::homePath)。