【cmake学习(1)】投入多余时间的文章
2024/09/12
编译dll
在项目属性中选择动态链接库,就可以将源文件转为dll。
要为dll对外提供函数接口,需要在函数声明中使用__declspec(dllimport)。
#define DLL __declspec(dllimport)
extern "C" DLL returntype function(arguements);
returntype function(arguements){
...
}
注意声明后不能定义。在dll中返回对象将只有地址,非常危险。
在python中使用dll
ctypes
模块提供了C类型到Python类型的转换,以及使用dll中函数的接口。
import ctypes as ct;
import random;
rd=ct.cdll.LoadLibrary('./Project1.dll')
rd.randout()
with open("out.txt","r+") as out:
li = out.readline().split(' ')
random.shuffle(li)
body = ' '.join(li)
with open('out2.txt','w+') as out:
out.write('1000\n'+body)
2024/10/04
Fusion 360体验
草图理念
以最简单的单视图设计为例,零件为一个平面图形的拉伸。
这句话包含平面图形
和拉伸
两个重要概念。零件——三维物体(模型),平面图形——草图,拉伸——创建、构造操作。
工作流程为:
-
绘制好草图
-
以草图为基础利用构造操作制造三维模型
于是,三维结构的特征就通过草图决定。
为了便于修改与表示草图元素之间的关联,提供了约束操作,可以指定线段平行、垂直等。
基础的拉伸操作有两种,为面拉伸、薄拉伸。
2024/10/24
C++程序设计
在vsc中添加c++扩展,在计算机中安装gcc,在命令行中使用gcc来编译.cpp源文件到.exe可执行文件。
gcc test.cpp -o debug/test.exe
-o
指定目标文件名称,-Wall
指定输出所有错误。
编译多文件,头文件会在当前目录下或系统头文件库寻找。第三方库不确定怎么用。
gcc main.cpp hello.cpp -o helloworld
但是vsc的内部终端不能浏览文件,所有要使用cmd或powershell来编译多文件。
可以独立编译各文件为.o,再编译成可执行文件。
g++ -Wall -c main.cpp hello.cpp
g++ main.o hello.o -o hw
对于windows,标准库的调用不需要显式链接。
要实现预处理,使用-D NAME=VALUE
g++ -DTEST=10 main.cpp hello.cpp -o debug/hw
以上在windows系统中有差错是,编译生成的文件一般用.obj。
文件分别生成.obj再链接的原因是,如果一直使用源码编译链接,每次都需要编译所有文件,在大型工程上是不利的。当全部.obj已经生成,那修改了的.cpp只需要再次编译替换原来的.obj即可。
库的打包与使用
见命令行工作。
gcc/g++还可以通过生成并使用.out文件来完成性能探查。
没有找到makefile的学习资料,不同厂商的makefile用法不同。
CMake+Visual Studio Code
安装CMake、C/C++扩展。
CMake使用有基本的三步:
-
指定CMake最低版本。
-
指定项目名称。
-
指定可执行文件名和源文件。
在CMakeLists.txt
中。
cmake_minimum_required(VERSION 3.30)
project(HelloWorld)
add_executable(helloworld helloworld.cpp)
然后在命令行中使用cmake 路径
、cmake --build 路径
。
分别在路径位置查找CMakeLists.txt
、CMakeCache.txt
,再在命令行所在位置生成编译、链接文件。
根据选择编译的模式不同,会使用不同的方法(编译器)编译,生成不同的中间文件。
这里默认应该是MVSC,虽然会多生成很多奇怪东西但是还可以不用组织目录。
cmake ./
cmake --build ./
如果要组织目录,首先将源文件、头文件和CMakeLists.txt
放在一个目录source
中,
cmake ./source
cmake --build ./
C++标准版本
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
切换编译器
mvsc的生成内容很多,希望使用mingw32-make编译,则在第一次使用cmake是加-G。
cmake -G "MinGW Makefiles" .
此时注意所有生成文件都默认在同目录下,生成的链接库会自动添加libXX.a,在要链接时只要填入XX。
link_library(greeting)
变量
cmake中有一系列变量,如PROJECT_SOURCE_DIR
、PROJECT_BINARY_DIR
,分别表示顶层CMakeLIsts.txt
所在目录、cmake生成目录。
在使用时用${PROJECT_SOURCE_DIR}
,可以用message命令来传出变量值。
message(STATUS "PROJECT_SOURCE_DIR:${PROJECT_SOURCE_DIR}")
链接库
多源文件的情况:
要生成静态库,使用add_library()
,用法与add_executable()
相同。
库中的函数在头文件中声明,外部变量在源文件中定义,而头文件中用extern声明外部变量,其他源文件只要包含该头即可。
要使用静态库,要添加静态库的目录位置到项目,使用link_library()
或link_directories()
。
注意生成静态库时,如果有同名文件,它并不会覆盖!所以要求先删去。g++、cmake编译出的lib不一定能互用。
有target_link_libraries()
和target_include_directories()
提供与上面类似的方法,但是可以指定要链接静态库目标的可执行目标。该方法必须放在可执行目标已经被add_executable()
生成之后。target_include_directories()
向目标添加寻找头文件的目录(有库的情况下相当于指定使用的库,库在前面已经指定)
add_library(greeting greeting.cpp)
add_executable(helloworld helloworld.cpp)
target_link_libraries(helloworld PUBLIC greeting)
备忘录 键盘如何烧录程序
这是一个编程手册
如何将程序烧录到开发板?
使用USB连接模式,
1.点RESET按钮进入DFU模式,然后打开dfu-programmer
输入
2.dfu-programmer atmega32u4 erase
3.dfu-programmer atmega32u4 flash ./你的程序文件
(这个程序在arduino中选择Teensy 2.0进行编程,
也就是说你的代码引脚也是参照teensy 2.0 编译后选择项目-》导出已编译的二进制文件,
打开项目文件夹,
.hex文件为你的程序)
4.dfu-programmer atmega32u4 reset
5.插拔USB
质点动力学的一道习题2.15
质点动力学的一道习题2.15
题目来自大学物理(少学时),高等教育出版社,第65页。
题目
在光滑水平桌面上,平放一个固定的半圆形屏障,质量为$m$的滑块以初速$v_0$沿切线方向进入屏障内,如题图2.15所示,设滑块与屏障间的摩擦因数为$\mu$,求证:当滑块从屏障另一端滑出时,摩擦力所做的功为:
$$ A=\frac{1}{2}mv_0^2(e^{-2\pi\mu}-1) $$ ![题图2.15.jpg][1] ## 故事以滑块运动方向为正方向。
开始以为有重力作用,满足:
$$ ma_\tau=P\sin\theta+F_f=m\frac{\text{d}v}{\text{d}r}=m\frac{\text{d}v}{\text{d}x}\frac{\text{d}x}{\text{d}t}=mv\frac{\text{d}v}{\text{d}x} \\ \ \\ ma_n=P\cos\theta+N=m\frac{v^2}{r} \\ \ \\ \text{d}A=F_f\,\text{d}x=F_fr\,\text{d}\theta \\ $$然后做不了一点,拿$\theta$没有办法。
$$ \frac{\text{d}v}{P\sin\theta-\frac{\mu}{r}v^2+\mu P\cos\theta}=\text{d}t \\ \ \\ \frac{v\ \text{d}v}{P\sin\theta-\frac{\mu}{r}v^2+\mu P\cos\theta}=\text{d}x $$一看题干发现
……,平放一个固定的半圆形屏障,……
没重力了……
$$ \begin{cases} F_f=ma_\tau=m\frac{\text{d}v}{\text{d}t}=m\frac{\text{d}v}{\text{d}x}\frac{\text{d}x}{\text{d}t}=-\mu N \\ \\ N=ma_n=m\frac{v^2}{r} \end{cases} \\ \ \\ \begin{align*} F_f=-\mu m\frac{v^2}{r}=mv\frac{\text{d}v}{\text{d}x} & \Rightarrow & -\mu m\frac{v^2}{r}\ \text{d}x=mv\ \text{d}v \\ & \Rightarrow & -\frac{\mu}{r}\ \text{d}x=\frac{\text{d}v}{v} \\ & \Rightarrow & \int_0^x-\frac{\mu}{r}\ \text{d}x=\int_{v_0}^v\frac{\text{d}v}{v} \\ & \Rightarrow & v=v_0e^{-\frac{\mu}{r}x} \end{align*} $$于是可以写出$F_f(x)$,可以进行积分$\int_0^{\pi r}F_f\ \text{d}x$。
$$ A=\int_0^{\pi r}-\mu m\frac{v^2}{r}\ \text{d}x=\frac{1}{2}mv_0^2(e^{-2\pi\mu}-1) $$如果不使用$F_f=m\frac{\text{d}v}{\text{d}x}\frac{\text{d}x}{\text{d}t}$而使用$m\frac{\text{d}v}{\text{d}t}$,则得到:
$$ v(t)=\frac{v_0r}{\mu v_0t+r} $$用不了一点。
总结
-
认真审题,细心答卷。
-
把“从屏障另一端滑出”翻译为从状态$(t=0,v=v_0,x=0)$到$(t=?,v=?,x=\pi r)$,立刻可知不要先尝试对$t$和$v$积分。
-
tamatamatama