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体验

草图理念

以最简单的单视图设计为例,零件为一个平面图形的拉伸。

这句话包含平面图形拉伸两个重要概念。零件——三维物体(模型),平面图形——草图,拉伸——创建、构造操作。

工作流程为:

  1. 绘制好草图

  2. 以草图为基础利用构造操作制造三维模型

于是,三维结构的特征就通过草图决定。

为了便于修改与表示草图元素之间的关联,提供了约束操作,可以指定线段平行、垂直等。

基础的拉伸操作有两种,为面拉伸、薄拉伸。


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.txtCMakeCache.txt,再在命令行所在位置生成编译、链接文件。

根据选择编译的模式不同,会使用不同的方法(编译器)编译,生成不同的中间文件。

这里默认应该是MVSC,虽然会多生成很多奇怪东西但是还可以不用组织目录。

cmake ./
cmake --build ./

d10c8bb2-21b8-4d4d-8bdd-17d4b626ad2c.png

如果要组织目录,首先将源文件、头文件和CMakeLists.txt放在一个目录source中,

cmake ./source
cmake --build ./

7bd08fd2-72e2-4818-9b16-ca7758bfdc67.png

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_DIRPROJECT_BINARY_DIR,分别表示顶层CMakeLIsts.txt所在目录、cmake生成目录。

在使用时用${PROJECT_SOURCE_DIR},可以用message命令来传出变量值。

message(STATUS "PROJECT_SOURCE_DIR:${PROJECT_SOURCE_DIR}")

链接库

多源文件的情况:

4a816a4f-6d49-4032-8ab2-39ebb185875a.png

要生成静态库,使用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

题目来自大学物理(少学时),高等教育出版社,第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