测试测试
编译Qt 4.8.7源码
一、先来看一篇转载文章《在 VS2015 中使用 Qt4》
http://tangzx.qiniudn.com/post-0111-qt4-vs2015.html 最早的原文,看不到了
https://github.com/district10/qt4-vs2015x64 原作者的github,里面的东东都下载不了了
二、firecat本人的教程
0、Qt官方
Qt4.8.7官方源码下载
https://download.qt.io/new_archive/qt/4.8/4.8.7/
官网的exe只提供了MSVC2010,没有更高版本的。高版本需要自己下载源码编译。
源码里面的配置文件已经提供了MSVC 2015的编译选项,\qt-everywhere-opensource-src-4.8.7\mkspecs\win32-msvc2015
参照官方提供的编译文档一步一步执行即可;但是配置文件里没有提供MSVC 2017的编译选项。
官方编译的文档
https://doc.qt.io/archives/qt-4.8/installation.html
https://doc.qt.io/archives/qt-4.8/configure-options.html
https://doc.qt.io/archives/qt-4.8/install-win.html
https://doc.qt.io/archives/qt-4.8/install-mac.html
https://doc.qt.io/qt-5/build-sources.html
1、Qt 4.8.7+MSVC 2017
推荐使用第三方提供的源码,它已经是修改好的,里面含有MSVC 2017编译选项,可以编译。
https://github.com/scharsig/Qt Qt4.8.7+MSVC2017源码
https://forum.qt.io/topic/91623/building-qt-4-8-7-with-visual-studio-2017 Qt4.8.7+MSVC2017论坛
https://github.com/sandym/qt-patches 仅供参考,编译补丁
https://github.com/Homebrew/formula-patches/tree/master/qt 仅供参考,编译补丁
https://github.com/BartVandewoestyne/qt_4_8_7_with_vs2017_patch 仅供参考,编译补丁
完整的编译过程:
下载第三方源码https://github.com/scharsig/Qt/tree/master/qt-4.8.7-vs2017 然后解压
-–step1—
Windows桌面-开始-程序-Visual Studio 2017-Visual Studio Tools-VC-x86 Native Tools Command Prompt for VS 2017
-–step2—
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise>cd F:\Qt\setup-exe\4.8.7\Qt-master\qt-4.8.7-vs2017
-–step3—
F:\Qt\setup-exe\4.8.7\Qt-master\qt-4.8.7-vs2017>configure -help
-–step4—
F:\Qt\setup-exe\4.8.7\Qt-master\qt-4.8.7-vs2017>
configure -make nmake -debug-and-release -opensource -confirm-license -platform win32-msvc2017 -prefix F:\Qt\Qt4.8.7-msvc2017 -nomake examples -nomake tests
如果不想编译这么多功能模块,可以精简为:
configure -make nmake -debug-and-release -opensource -confirm-license -platform win32-msvc2017 -prefix F:\Qt\Qt4.8.7-msvc2017 \
-no-qt3support -no-multimedia \
-no-audio-backend -no-phonon -no-phonon-backend -no-libtiff \
-no-libmng -no-dbus -no-nis -nomake examples -nomake tests
-release Compile and link Qt with debugging turned off. -debug Compile and link Qt with debugging turned on. -nomake tests Disable building of tests to speed up compilation -nomake examples Disable building of examples to speed up compilation -confirm-license Automatically acknowledge the LGPL 2.1 license.
-–step5—
F:\Qt\setup-exe\4.8.7\Qt-master\qt-4.8.7-vs2017>nmake
-–step6—
F:\Qt\setup-exe\4.8.7\Qt-master\qt-4.8.7-vs2017>nmake install
-–step7—
添加到Qt Creator
-–step8—
新建项目测试,Qt Creator+Qt4.8.7+MSVC2017编译项目时,如果报错:
intermediate\moc\moc_rs_actionzoompan.cpp:-1: error: C1041: 无法打开程序数据库“F:\CADCAM\QCAD\src\build-LibreCAD-v1.0.4-qt4-Desktop_Qt_4_8_7_MSVC2017_32bit-Debug\librecad\vc140.pdb”;如果要将多个 CL.EXE 写入同一个 .PDB 文件,请使用 /FS
解决办法:
在Qt Creator的项目文件,即.pro文件中,可以通过QMAKE_CXXFLAGS来给MSVC编译器传递编译开关。
QMAKE_CXXFLAGS += /FS
win32-msvc*:QMAKE_CXXFLAGS += /wd"4819" QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO -= -Zc:strictStrings
MSVC 2017编译器常见错误的解决:
2、Mac OS+Qt 4.8.7
笔者的Mac OS版本是MacOS-10.15-Catalina,高版本的OS和Clang已经不再支持Qt官方发布的Qt4了。
解决办法可以参见我的另一篇博文:https://blog.csdn.net/libaineu2004/article/details/104740623
https://trac.macports.org/ticket/58651 mac下编译qt4遇到问题
https://github.com/macports/macports-ports/tree/master/aqua/qt4-mac mac编译补丁
Podman配置代理
方法1: 为当前用户设置环境变量
为当前用户设置 HTTP_PROXY 和 HTTPS_PROXY 环境变量,Podman 将自动读取这些环境变量并使用代理。
1 | # Bash |
如果代理需要身份验证,可以在 URL 中添加用户名和密码。格式如下:
1 | http://用户名:密码@代理地址:端口 |
方法2:为 Podman 服务设置配置文件
通过编辑 /etc/containers/registries.conf 配置文件为 Podman 服务设置代理。在该文件中添加如下内容:
1 | [registries.search] |
替换 REGISTRY_NAME.HOSTNAME 为您要配置的注册表,如 docker.io。如果代理需要身份验证,则使用类似 http://user:password@proxy.example.com:8080 的格式。
方法3: 为单个 Podman 命令设置代理
为单个 Podman 命令临时设置代理,方法是在命令前添加 –build-arg 参数。例如:
1 | podman --build-arg HTTP_PROXY="http://代理地址:端口" --build-arg HTTPS_PROXY="https://代理地址:端口" pull nginx |
方法四: 配置 http-proxy.conf
1 | $ systemctl status podman |
使用Podman替代DockerDesktop
安装依赖环境
1
2
3
4
5
6
7
8# 启用虚拟化平台
dism /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
# 启用linux子系统
dism /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all
wsl --install
wsl --update安装Podman
1
2
3
4
5
6
7
8
9
10
11
12
13
14# 安装DockerCLI,用于兼容Docker命令
winget install --id Docker.DockerCLI
# 安装Podman
winget install --id RedHat.Podman
# 安装Podman Desktop (可选)
winget install --id RedHat.Podman-Desktop
# 初始化Podman
podman machine init
# 配置端口转发
wsl sudo sysctl net.ipv4.ip_forward=1配置wsl虚拟机
1
2
3
4
5
6
7# 修改默认软件源
sudo sed -e 's|^metalink=|#metalink=|g' \
-e 's|^#baseurl=http://download.example/pub/fedora/linux|baseurl=https://mirrors.tuna.tsinghua.edu.cn/fedora|g' \
-i.bak \
/etc/yum.repos.d/fedora.repo \
/etc/yum.repos.d/fedora-updates.repo
sudo dnf makecache测试
1
docker run --rm -d -p 80:80 --name httpd docker.io/library/httpd:latest
配置镜像加速
podman的配置文件在容器内/etc/containers/registries.conf
,配置格式如下1
2
3
4
5unqualified-search-regustrues = ["docker.io"]
[[registry]] # 注意此处配置不需要加'https'
prefix = "docker.io" # 访问地址
location = "docker.m.daocloud.io" # 加速地址配置私有镜像库
1 | [[registry]] |
如果访问地址为https
需要配置信任证书
1 | sudo mkdir /etc/containers/certs.d |
- 配置文件翻译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68# 有关此配置文件的更多信息,请参阅 containers-registries.conf(5)。
#
# 注意:使用未完全限定镜像名称的风险
# 我们建议始终使用包括注册表服务器(完整 DNS 名称)、命名空间、镜像名称和标签在内的完全限定镜像名称
# (例如,registry.redhat.io/ubi8/ubi:latest)。通过摘要(例如,
# quay.io/repository/name@digest)拉取镜像可以进一步消除标签的不确定性。
# 使用短名称时,始终存在镜像被伪造的风险。例如,用户想从某个注册表中拉取名为
# `foobar` 的镜像,并期望该镜像来自 myregistry.com。如果
# myregistry.com 不是搜索列表中的第一个,攻击者可能会在列表中靠前的位置
# 放置另一个名为 `foobar` 的镜像。用户可能会意外拉取并运行攻击者的镜像和代码,而不是
# 预期的内容。我们建议只添加完全可信的注册表(即,不允许未知或匿名用户
# 创建任意名称的账户的注册表)。这将防止镜像被伪造、抢占或以其他方式变得不安全。
# 如果有必要使用这些注册表,它应该添加到列表的末尾。
#
# # 一个主机[:端口]格式的注册表数组,当拉取未完全限定镜像时,按顺序尝试这些注册表。
unqualified-search-registries = ["registry.fedoraproject.org", "registry.access.redhat.com", "docker.io"]
#
# [[registry]]
# # "prefix" 字段用于选择相关的 [[registry]] TOML 表;
# # 使用输入镜像名称时,只有与该名称最长匹配的 TOML 表会被使用
# # (考虑到命名空间/库/标签/摘要分隔符)。
# #
# # 如果缺少 prefix 字段,则默认与 "location" 字段相同。
prefix = "example.com/foo"
#
# # 如果为 true,则允许未加密的 HTTP 连接以及使用不受信任证书的 TLS 连接。
insecure = false
#
# # 如果为 true,则禁止拉取匹配名称的镜像。
blocked = false
#
# # "prefix" 所在命名空间的物理位置。
# #
# # 默认情况下,与 "prefix" 相同(在这种情况下,可以省略 "prefix",并且 [[registry]] TOML 表只指定 "location")。
# #
# # 例如:假设
# # prefix = "example.com/foo"
# # location = "internal-registry-for-example.net/bar"
# # 那么对镜像 example.com/foo/myimage:latest 的请求实际上会与
# # internal-registry-for-example.net/bar/myimage:latest 镜像匹配。
location = "internal-registry-for-example.com/bar"
#
# # "prefix" 所在命名空间的(可能部分的)镜像。
# #
# # 将按指定顺序尝试这些镜像;第一个可以联系到并包含镜像的将被使用
# # (如果所有镜像都没有该镜像,则最后尝试 "registry.location" 字段指定的主位置,或者使用未修改的用户指定引用)。
# #
# # "mirror" 数组中的每个 TOML 表可以包含以下字段,语义与直接在 [[registry]] TOML 表中指定的相同:
# # - location
# # - insecure
[[registry.mirror]]
location = "example-mirror-0.local/mirror-for-foo"
[[registry.mirror]]
location = "example-mirror-1.local/mirrors/foo"
insecure = true
# # 根据上述配置,拉取 example.com/foo/image:latest 时将按顺序尝试:
# # 1. example-mirror-0.local/mirror-for-foo/image:latest
# # 2. example-mirror-1.local/mirrors/foo/image:latest
# # 3. internal-registry-for-example.net/bar/image:latest
# # 并使用第一个存在的镜像。
#
# short-name-mode="enforcing"
# 强制使用完全限定镜像名称
[[registry]]
location="localhost:5000"
insecure=true
# 允许使用不安全的连接拉取本地镜像。
公司常见后缀的含义
1. Co., Ltd.
- 全称:Company Limited
- 含义:有限责任公司,常见于英国、中国及亚洲地区
- 特点:”Co.“为Company缩写,”.“表示缩写符号,”,”用于分隔前后词
2. Inc.
- 全称:Incorporated
- 含义:股份有限公司,多用于美国、加拿大
- 示例:Apple Inc.,强调股东责任限于股份投资
3. LLC
- 全称:Limited Liability Company
- 含义:有限责任公司(美国特有形式)
- 特点:兼具合伙制灵活性与股份制有限责任,如Google LLC
4. GmbH
- 全称:Gesellschaft mit beschränkter Haftung
- 含义:有限责任公司,德国及德语区专用
- 示例:Bosch GmbH1
5. AG
- 全称:Aktiengesellschaft
- 含义:股份有限公司,德国及瑞士常见
- 示例:BMW AG
6. S.A.
- 全称:Société Anonyme(法)/Sociedad Anónima(西)
- 含义:股份有限公司,流行于法国、西班牙等拉丁语系国家
- 示例:L’Oréal S.A.1
7. Plc
- 全称:Public Limited Company
- 含义:公众有限公司(英国上市企业专用)
- 示例:HSBC Holdings plc1
8. 株式会社(Kabushiki Kaisha)
- 缩写:KK
- 含义:日本股份有限公司
- 示例:Toyota Motor Corporation KK
地域差异提示:
- 英国”Ltd.”与美国”LLC”虽均表有限责任,但法律结构不同
- 荷兰用”BV”(私人有限公司),意大利用”S.p.A.”(股份公司)
K3s部署Tekton
Linux实现U盘插入自动挂载
方式一
通过udev
规则监听设备事件,编写/etc/udev/rules.d/99-udev-mount.rules
规则实现U盘插入捕获U盘插入事件
1 | # 插入U盘自动挂载 |
规则编辑完成后执行以下命令使规则生效
1 | sudo udevadm control --reload |
Python对接C库
1. 准备环境
- 准备开发包:包含头文件(
.h
)、库文件(.dll或.so
)及对接文档 - 安装依赖:确保Python环境已安装
ctypes
库或第三方库例如Cython
(用于复杂场景) - 配置路径:将SDK的库路径添加到环境变量或直接在代码中指定路径(推荐方式,不会因为换电脑导致无法编译,例如
sdk/windows/sdk.dll
)
2. 封装接口
加载SDK
1 | import sys |
定义结构体
1 | # 定义结构体,需要与SDK头文件一致 |
![[Python对接C库/IMG-20250804110742707.png]]
定义函数原型,需严格对齐SDK中的数据类型和函数参数顺序
1 | sdk.Init.restype = c_bool # 映射返回值,Init为C/C++中的函数名 |
3. 接口调用
函数调用
1 | sdk.Init(c_int(0), c_int_p(0), c_char_p(b"this is a test")) |
带有回调函数的函数调用
回调函数例如
1 | int (*Callback) (int, char*); |
Python中定义回调函数类型
1 | CallbackType = CFUNCTYPE(c_int, c_int, c_char_p) # 返回类型在前,参数在后 |
若C函数使用__stdcall
(常见于Windows API),需要WINFUNCTYPE
替代CFUNCTYPE
,若为__cdecl
(默认),则使用CFUNCTYPE
Python实现回调函数(参数和返回值需与C定义严格一致)
1 | def py_callback(num, text) -> int: |
处理指针参数
若回调参数包含指针,例如void*
,需要使用c_void_p
类型,并通过cast解析
1 | def py_callback(data_ptr): |
注册回调函数
1 | c_callback = CallbackType(py_callback) # 使用定义的回调类型包装Python函数 |
4. 资源释放
退出时需要调用SDK中的清理函数释放资源
1 | sdk.Cleanup() |
5. 注意事项
- 结构体指针和缓冲区需要手动分配/释放,避免内存泄漏
- 不同版本SDK接口可能有差异,建议统一开发与部署环境
- 映射Windows中特有的类型例如
WORD
,DWORD
在wintypes
包中 - C调用Python回调时,若Python函数抛出异常可能导致程序崩溃。需要在回调内部处理异常。
- 若C函数在子线程中调用回调,需确保Python的GIL(全局解释锁)已获取
1
2
3
4
5
6
7from ctypes import py_object, pythonapi
PyGILState_Ensure = pythonapi.PyGILState_Ensure
PyGILState_Release = pythonapi.PyGILState_Release
def thread_safe_callback():
state = PyGILState_Ensure()
# 执行Python操作
PyGILState_Release(state)
Golang检查目录是否存在
使用os.stat()
1 | package main |
使用os.open()
1 | package main |
使用mkdir()
1 | package main |
Golang实现SM4
ECB模式,PKCS5填充
1 | package sm4 |