考虑一下:
- 将 Python 嵌入的到 C++ 中,编译出一个可执行程序
- 并将 Python 的文件(.py, .so, .pyd,等)放到可执行程序所在目录的某个子目录
那么,嵌入的Python如何找到这些文件呢?
需要知道可执行程序自身路径,可是,C、C++ 标准库没有提供这种东西
只能使用系统api了,而系统api用起来需要注意的问题似乎总是不少,
不过呢,Qt 中提供的这种功能,我们不妨看看它是如何做的:
Qt Manual
QString QCoreApplication::applicationFilePath () [static]
Returns the file path of the application executable.
For example, if you have installed Qt in the /usr/local/qt directory, and you run the regexp example, this function will return "/usr/local/qt/examples/tools/regexp/regexp".
Warning: On Linux, this function will try to get the path from the /proc file system. If that fails, it assumes that argv[0] contains the absolute file name of the executable. The function also assumes that the current directory has not been changed by the application.
恩,这儿已经介绍了 Linux 下是如何实现的了,不过还是看看源码吧,毕竟,
在离开Qt的C++下,需要我们自己写类似的代码。
Unix/Linux
源码如下:
#if defined( Q_OS_UNIX )
# ifdef Q_OS_LINUX
// Try looking for a /proc/<pid>/exe symlink first which points to
// the absolute path of the executable
QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
if (pfi.exists() && pfi.isSymLink()) {
d->cachedApplicationFilePath = pfi.canonicalFilePath();
return d->cachedApplicationFilePath;
}
# endif
QString argv0 = QFile::decodeName(QByteArray(argv()[0]));
QString absPath;
if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
/*
If argv0 starts with a slash, it is already an absolute
file path.
*/
absPath = argv0;
} else if (argv0.contains(QLatin1Char('/'))) {
/*
If argv0 contains one or more slashes, it is a file path
relative to the current directory.
*/
absPath = QDir::current().absoluteFilePath(argv0);
} else {
/*
Otherwise, the file path has to be determined using the
PATH environment variable.
*/
QByteArray pEnv = qgetenv("PATH");
QDir currentDir = QDir::current();
QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1Char(':'));
for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
if ((*p).isEmpty())
continue;
QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
QFileInfo candidate_fi(candidate);
if (candidate_fi.exists() &&
Windows
Windows 提供了 GetModuleFileName 这种函数,所以操作就容易多了,不过Qt源码中也还是一大段哈。
- 首先,假定路径总长度不超过 MAX_PATH(当前情况下,其值仍然是260,似乎微软也没有动它的打算?)
- 在 栈 上分配一个 MAX_PATH + 2 长度的数组
- 如果真实的长度超过了 MAX_PATH,就改用在 堆 中分配内存
- 分配 2倍MAX_PATH,进行尝试
- 依然不行,则分配 3倍 MAX_PATH,
- ...
// We do MAX_PATH + 2 here, and request with MAX_PATH + 1, so we can handle all paths
// up to, and including MAX_PATH size perfectly fine with string termination, as well
// as easily detect if the file path is indeed larger than MAX_PATH, in which case we
// need to use the heap instead. This is a work-around, since contrary to what the
// MSDN documentation states, GetModuleFileName sometimes doesn't set the
// ERROR_INSUFFICIENT_BUFFER error number, and we thus cannot rely on this value if
// GetModuleFileName(0, buffer, MAX_PATH) == MAX_PATH.
// GetModuleFileName(0, buffer, MAX_PATH + 1) == MAX_PATH just means we hit the normal
// file path limit, and we handle it normally, if the result is MAX_PATH + 1, we use
// heap (even if the result _might_ be exactly MAX_PATH + 1, but that's ok).
wchar_t buffer[MAX_PATH + 2];
DWORD v = GetModuleFileName(0, buffer, MAX_PATH + 1);
buffer[MAX_PATH + 1] = 0;
if (v == 0)
return QString();
else if (v <= MAX_PATH)
return QString::fromWCharArray(buffer);
// MAX_PATH sized buffer wasn't large enough to contain the full path, use heap
wchar_t *b = 0;
int i = 1;
size_t size;
do {
++i;
size = MAX_PATH * i;
b = reinterpret_cast<wchar_t *>(realloc(b, (size + 1) * sizeof(wchar_t)));
if (b)
v = GetModuleFileName(NULL, b, size);
} while (b && v == size);
if (b)
*(b + size) = 0;
QString res = QString::fromWCharArray(b);
free(b);
分享到:
相关推荐
QT c++ dijkstra最短路径工程源码
基于Qt和C++实现的故宫游览路径规划程序源码.zip基于Qt和C++实现的故宫游览路径规划程序源码.zip基于Qt和C++实现的故宫游览路径规划程序源码.zip基于Qt和C++实现的故宫游览路径规划程序源码.zip基于Qt和C++实现的...
基于C_C++ Qt5开发跨平台桌面程序网络调试应用源码+项目说明.zip 【项目介绍】 基于C/C++ Qt5开发跨平台桌面程序应用,使用TCP/IP、UDP/IP网络协议,B/S、C/S架构,实现上下位机、客户端与服务器之间网络通信调试。 ...
C++程序开发基于Qt实现的简单绘画板程序源码+项目说明(课程大作业) 功能介绍 绘制点、直线、椭圆、矩形等基本几何图形; 存储、读取绘图文件; 撤回、重做等功能; 调节线宽、线条颜色; 显示鼠标坐标位置。 注意...
Qt步进电机上位机控制程序源代码Qt跨平台C C++语言编写 支持串口Tcp网口Udp网络三种端口类型 提供,提供详细注释和人工讲解 1.功能介绍: 可控制步进电机的上位机程序源代码,基于Qt库,采用C C++语言编写。 支持...
C++程序开发基于Qt实现的简单绘画板程序源码+项目说明.zip 基于Qt实现的简单绘画板程序。 ## 功能介绍 - 绘制点、直线、椭圆、矩形等基本几何图形; - 存储、读取绘图文件; - 撤回、重做等功能; - 调节线宽、线条...
基于OpenCV+QT+C++的路径规划系统源码+使用文档+全部资料(优秀项目).zip基于OpenCV+QT+C++的路径规划系统源码+使用文档+全部资料(优秀项目).zip基于OpenCV+QT+C++的路径规划系统源码+使用文档+全部资料(优秀...
qt 解析 svg 所有路径信息 源码
二维码 QT生成程序 测试通过 C++,为了编译不通过的同志使用~ Linux环境下QT中实现二维码生成有两种方法,这两种方法都需要用到开源的代码--qrencode。第一种方法是下载qrencode源码后,将其移植到目标板子上,然后...
C++开发基于TCPsocket实现的web服务器源码。基于TCP socket实现的支持报文解析并返回响应报文的Web服务器,可以响应多种文件需求并能够处理特定的错误情况 服务器实现及其功能: 1、读取配置文件,为服务器自身设置...
QT C++ 下测试QXmlStreamReader与PugiXml效率对比源码 使用Qt5.6.1环境,只对比了QXmlStreamReader与PugiXml的效率, 测试前,将源码路径下的large.xml拷贝到执行程序路径下 需要自行编译 代码使用截止日期:2020...
资源包含文件:设计报告word+PPT+用户使用说明文档等+项目源码及数据库文件+演示视频 软件开发环境: Qt,MySQL 总体结构和模块划分 Widget与map,MySQL,way模块单向交互 Map模块:定义地图子窗口,实现绘制旅客...
C++基于QT开发的个人音乐播放器项目源码+项目说明+详细注释(课程作业).zip 基于qt,c++实现的个人音乐播放小项目(源码) # 主要功能 主要使用QMediaPlayer库添加文件夹进行音乐播放; 实现了进度条控制自动根据音乐时间...
毕业设计 课程设计 系统设计 系统开发 C++ QT 数据库 源代码 毕业设计 课程设计 系统设计 系统开发 C++ QT 数据库 源代码 毕业设计 课程设计 系统设计 系统开发 C++ QT 数据库 源代码 毕业设计 课程设计 系统设计 ...
基于qt和C++的ROS 人机交互界面源码+运行使用说明+效果图.zip基于qt和C++的ROS 人机交互界面源码+运行使用说明+效果图.zip ROS qt 人机交互界面 - 实现图像显示,可以自动刷新图像类型画图 - 实现GPS显示,速度显示...
\阅读本书的读者需要具有基本的C++程序设计知识,毕竟Qt是用C++编写的应用程序框架。如果要学习QtScript,还需要了解JavaScript。 \本书的结构 \本书共21章,每章讨论一个专题。章节安排上基本采用循序渐进、由浅...
基于Qt+C++开发的室外基于GPS的无人机分布式编队避障飞行项目源码+开发文档说明+实验数据报告,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于Qt+C++开发的...
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。...基于opencv和QT的路径规划系统源码.zip
Qt实现的腾讯地图加载,使用QWebEngine内嵌浏览器的方式,需要...通过修改源码中load路径使用,JavaScript可放在本地,也可挂在http服务器上,修改url即可。 Debug加载QWebEngine地图显示较慢,建议使用Release编译。