一些问题的解决方案【持续更新ing】

记录一些问题(主要为VS或windows\ubuntu使用过程中的问题)的解决方案,一些即时学到的解决方案往往不进脑子,为了避免第二次遇到同样问题时不被自己骂,那么就只能好记性不如烂笔头了


Windows


CUDA 安装失败解决方案

在CUDA安装时报错
或在安装其他程序时提示正在安装另一个程序等等

解决方案
打开任务管理器,在进程中搜索msiexec.exe安装程序
将后台运行的msiexec.exe结束运行,然后重新运行安装程序,让其能够重新正常调用msiexec.exe

在这里插入图片描述


VS 添加现有项无反应

关闭.sln
删除工程目录下的.vs 缓存文件夹
重新打开.sln


VS 无法定位程序输入点 于动态链接库 xxx.exe 上

在这里插入图片描述
版本不一致,检查新生成dll版本的接口与生成exe的接口(头文件.h)是否一致。


VS 不同工具集生成的库无法通用

当然是更改工具集重新生成

在这里插入图片描述
重新生成
在这里插入图片描述

在这里插入图片描述


VS dll与exe联调

1.输出目录

在常规-输出目录下设置dll的输出路径,一般是与exe同级目录
在这里插入图片描述

2.命令
在调试-命令中输入exe所在路径
3.工作目录
将工作目录改为 .

在这里插入图片描述
如此可以提前打好断点,生成dll后,进行调试,会自动启动相关exe,在exe中执行相关功能后会运行至在断点处停止,也可以增删断点,调试起来很方便


VS dll与exe联调basepath报错

dll与exe联调时报错如下:

Basepath argument is not fully qulified. 参数名:basePath

在这里插入图片描述
像这种就是因为命令参数出了问题,但是打开调试页面发现exe路径是对的,非常奇怪的错误,最后发现是我拷贝的路径有问题…

这里复现一下我拷贝某个文件的完整路径常用方法
以Chrome为例,我会打开其属性面板,然后在安全栏下,有一个对象名称,里面有该文件的绝对路径

在这里插入图片描述
选中复制粘贴可得

D:\Program Files\Google\Chrome\Application\chrome.exe

在大部分情况下,它是正常的,但是其实它在开头有概率会遇到特殊符号,比如在Git Bash中粘贴并回车可以发现

其前面为\342\200\252D:Program,这就是错误的根源

所以这种获取绝对路径的习惯还得改改,或者每次拷贝后删除前面的D:\(感觉如果不能一步完事还不如不用这个方法)

在这里插入图片描述

只要路径输对,VS能够正确找到exe,那么就不会有以上Basepath报错


VS F12或Ctrl+鼠标左键单击 跳转位置不准

打开【工具】->【选项】,在【文本编辑器中】->【C/C++】的【高级】菜单里的【浏览/导航】下,将【重新创建数据库】设置为【True】,然后保存工程后重启VS,再测试发现问题已解。

在这里插入图片描述


更改只读属性

CMD终端中使用attrib命令

C:\Users>help attrib
显示或更改文件属性。
ATTRIB [+R | -R] [+A | -A ] [+S | -S] [+H | -H] [+I | -I]
       [drive:][path][filename] [/S [/D] [/L]]
  + 设置属性。
  - 清除属性。
  R 只读文件属性。
  A 存档文件属性。
  S 系统文件属性。
  H 隐藏文件属性。
  I 无内容索引文件属性。
  [drive:][path][filename]
      指定 attrib 要处理的文件。
  /S 处理当前文件夹及其所有子文件夹中的匹配文件。
  /D 也处理文件夹。
  /L 处理符号链接和符号链接目标的属性。

卸载被系统占用的dll

背景是将一个dll(mfplat.dll)从C:\Windows\SysWOW64 拷贝到 C:\Windows\System32下,然后被系统识别占用,尝试了以下方法,删除时显示拒绝访问,实际上是,相关进程没有结束或者结束后立马重启

1. 打开命令提示符(以管理员身份运行)。
2. 使用 `tasklist /m <dll_name>` 命令查找使用该 DLL 的进程。
3. 使用 `taskkill /PID <process_id> /F` 命令结束相关进程。
4. 使用 `del <file_path>` 命令删除 DLL 文件。

最终决定在安全模式下通过命令行解决

选择高级重启,有的可以在重启时通过快捷键进入
在这里插入图片描述
选择以安全模式命令行方式解决

这里如果有涉及到BitLocker,需要登录微软账号,在个人设备里面查看BitLocker 恢复密钥

打开命令行后,显示为X:/Windows/System32,依次输入

C:
cd Windows
cd System32
del mfplat.dll
exit

重新进入系统,可见被占用的dll已被成功删除


应用程序无法正常启动&Windows卸载更新

在这里插入图片描述
某程序启动报错:应用无法正常启动(0xc000007b),最终定位到是不久前系统更新问题(太坑了!),计划卸载更新后重试

直接搜索卸载更新

在这里插入图片描述

打开后可以看到近来的更新,卸载可能有问题的更新,再重启

在这里插入图片描述

重启后重新打开程序,正常运行


Ubuntu


VTK cmake 过程中找不到QT5目录

cmake-gui 中,勾选VTK_Group_QT后,Configure报错:

  By not providing "FindQt5.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "Qt5", but
  CMake did not find one.

  Could not find a package configuration file provided by "Qt5" with any of
  the following names:

    Qt5Config.cmake
    qt5-config.cmake

  Add the installation prefix of "Qt5" to CMAKE_PREFIX_PATH or set "Qt5_DIR"
  to a directory containing one of the above files.  If "Qt5" provides a
  separate development package or SDK, be sure it has been installed.

解决方案:

手动填上Qt5_DIR的地址,地址要精确到Qt5Config.cmake所在文件夹(windows平台也一样)

ubuntu中如:

/opt/Qt5.12.5/5.12.5/gcc_64/lib/cmake/Qt5

填上后,Configure+Generate:
在这里插入图片描述



Ubuntu添加环境变量(永久+最简单)

Ctrl+Atl+T 打开Shell

sudo vim /etc/environment

(没有安装vim或没有接触过vim可用默认文本编辑器gedit打开编辑)

sudo gedit /etc/environment

PATH=后以冒号分隔,添加路径(执行文件所在目录的绝对路径)

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/wj/WW3/model/exe:/home/wj/WW3/model/bin:/usr/local/openmpi:/usr/local/VSCode-linux-x64/"

保存,注销重新登录即可生效


Wandb强制终止

某些情况下Ctrl+C结束网络训练时,终端仍一直输出

wandb-servicef xxx MB uploaded (xxx MB deduped)

可输入如下命令终止wandb服务

pkill wandb-service

一步执行多条命令

如 创建文件夹并进入,常用于cmake

似乎用处不大,极少数情况下或许能装一下?

mkdir [folder] && cd $_

mkdir 创建命令
[folder]文件夹名字
&& 并且(接着执行后面的命令)
cd 进入文件夹
$_ 上一个命令的最后参数


Ubuntu 触摸板开关

针对设置里面的触摸板开关无效的情况(之前的联想拯救者在ubuntu下有这个bug)

可使用xinput命令启用和禁用触摸板。首先,输入xinput查看触摸板的名称或ID,例如:


~ > xinput                                     
⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ Asus Keyboard                           	id=14	[slave  pointer  (2)]
⎜   ↳ ELAN1200:00 04F3:303E Mouse             	id=15	[slave  pointer  (2)]
⎜   ↳ Logitech G304                           	id=12	[slave  pointer  (2)]
⎜   ↳ ELAN1200:00 04F3:303E Touchpad          	id=16	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Asus Wireless Radio Control             	id=7	[slave  keyboard (3)]
    ↳ Video Bus                               	id=8	[slave  keyboard (3)]
    ↳ Video Bus                               	id=9	[slave  keyboard (3)]
    ↳ Power Button                            	id=10	[slave  keyboard (3)]
    ↳ Sleep Button                            	id=11	[slave  keyboard (3)]
    ↳ USB2.0 HD UVC WebCam: USB2.0 HD         	id=13	[slave  keyboard (3)]
    ↳ Asus WMI hotkeys                        	id=17	[slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard            	id=18	[slave  keyboard (3)]
    ↳ Asus Keyboard                           	id=20	[slave  keyboard (3)]
    ↳ Logitech G304                           	id=19	[slave  keyboard (3)]

查看输出得知触摸板设备名id,接下来可以使用如下命令:

禁用触摸板

xinput --disable 16

打开触摸板

xinput --enable 16

查看当前文件夹的大小

du -sh
❯ du -sh                                     🐍 base root@sdfstudio  17:04:36
186G    .

C++


#pragma omp parallel for

#pragma omp parallel for 是一个 OpenMP 指令,用于在多核处理器或多处理器系统上实现并行化循环的执行

使用 #pragma omp parallel for 的一些注意事项:

  • 数据依赖性:确保循环中没有数据竞争或依赖,否则可能导致不正确的结果或竞态条件
  • 效率:并非所有的循环都适合并行化。对于简单或迭代次数较少的循环,并行化的开销可能会超过其带来的性能提升
  • 调度策略:可以使用 schedule 子句来控制循环迭代如何被分配给线程

反面例子(使用#pragma omp parallel for 计算出错,注释#pragma omp parallel for 后计算正确)

double ct1[3] = { 0 };
#pragma omp parallel for
	for (int i = 0; i < point_number; ++i)
	{
		ct1[0] += m_cloud_sample_target[i].x;  
		ct1[1] += m_cloud_sample_target[i].y;  
		ct1[2] += m_cloud_sample_target[i].z; 
	}
	ct1[0] /= point_number;
	ct1[1] /= point_number;
	ct1[2] /= point_number;

原因是在 #pragma omp parallel for 指令下,每个线程都会并行执行循环体中的代码。由于 ct1 数组是共享的,多个线程会同时对其进行累加操作,导致数据竞争。这样,某个线程可能会在另一个线程更新 ct1 之前读取旧值,从而导致错误的累加结果[来自GPT]

注释掉 #pragma omp parallel for 后,代码以串行方式执行,不存在数据竞争问题,因此计算结果正确


extern “C”

extern "C" 是 C++ 中的一个关键字组合,用于告诉编译器按照 C 语言的链接约定来处理函数或变量。这通常在 C++ 程序中调用 C 语言库的函数,或者在 C 语言程序中调用 C++ 编写的函数时使用。

作用:

  1. 防止名称修饰(Name Mangling)

    • C++ 编译器会对函数名进行修饰(也称为名称编码或名称装饰),以便包含函数的参数类型和数量信息。这有助于重载和模板等特性。
    • C 语言没有这样的名称修饰机制。因此,当你在 C++ 程序中声明一个要被 C 代码调用的函数时,你需要使用 extern "C" 来禁用名称修饰,确保 C 和 C++ 代码中函数的名称是一致的。
  2. 链接兼容性

    • 使用 extern "C" 可以确保 C++ 函数与 C 代码中的函数具有相同的链接约定,从而可以在 C 和 C++ 代码之间互相调用。

注意:

  1. 仅用于声明:

    • extern "C" 仅用于函数或变量的声明,而不是定义。
    • 实际的函数实现仍然需要在 C 或 C++ 文件中。
  2. 不改变函数行为:

    • extern "C" 不影响函数的行为或返回值,它仅影响函数的链接约定。

假设你有一个 C 语言库,你想在 C++ 程序中使用它。首先,你需要在 C++ 程序中声明 C 语言库中的函数,并使用 extern "C" 关键字。

extern "C" void
launch_classifyVoxel(dim3 grid, dim3 threads, uint *voxelVerts, uint *voxelOccupied, uchar *volume,
                     uint3 gridSize, uint3 gridSizeShift, uint3 gridSizeMask, uint numVoxels,
                     float3 voxelSize, float isoValue);

还可以使用 extern "C" 包裹一组函数声明:

extern "C" {
    void myFunction1(int a);
    void myFunction2(double d);
    // ...
}

FILE、__FUNCTION__和 __LINE__的使用

调试时输出文件名、方法名和行号

printf("Error at file: %s, function: %s, line: %d\n", __FILE__, __FUNCTION__, __LINE__);

__FILE__ 返回的文件名通常包含路径信息,如果不需要路径信息,可以写一个函数来去除路径,获取文件的基本名称,如

#include <iostream>
#include <string>

std::string basename(const char* path)
{
    std::string fileName(path);
    size_t lastSlash = fileName.find_last_of("/\\");
    if (lastSlash != std::string::npos) {
        fileName = fileName.substr(lastSlash + 1);
    }
    return fileName;
}

void MyFunction() {
    std::cout << "Error at file: " << basename(__FILE__) << ", function: " << __FUNCTION__ << ", line: " << __LINE__ << std::endl;
}

int main() {
    MyFunction();
    return 0;
}

当然也可以用std::cout,如

#include <iostream>
#include <string>

std::string basename(const char* path)
{
    std::string fileName(path);
    size_t lastSlash = fileName.find_last_of("/\\");
    if (lastSlash != std::string::npos) {
        fileName = fileName.substr(lastSlash + 1);
    }
    return fileName;
}

void MyFunction() {
    std::cout << "Error at file: " << basename(__FILE__) << ", function: " << __FUNCTION__ << ", line: " << __LINE__ << std::endl;    // 小项目只输出__FUNCTION__和__LINE__就够用了
}

int main() {
    MyFunction();
    return 0;
}

Python


绘制等比例坐标轴

二维:
坐标轴等比例

plt.axis('equal')
or
plt.axis('scaled')

axis()相关方法

axis()
	[xmin, xmax, ymin, ymax]:显示坐标轴的范围
	option,可取值为
	'on':打开坐标轴
	'off':关闭坐标轴显示
	'equal':设置相等的比例,y轴和x轴单位刻度对应长度是一样的
	'scaled':通过更改绘图框的尺寸设置相等的缩放比例
	'tight':设置足够大的限制来显示所有数据
	'auto':自动确定
	'image':‘scaled’ with axis limits equal to data limits
	'square':方形图,类似于‘scaled’,但是强制xmax-xmin = ymax-ymin

三维:

坐标轴等比例

ax.set_box_aspect([ub - lb for lb, ub in (getattr(ax, f'get_{a}lim')() for a in 'xyz')])

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WoooChi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值