commit
This commit is contained in:
commit
a3ee34a1da
BIN
assert/1.png
Normal file
BIN
assert/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
BIN
assert/image-20240809145202119.png
Normal file
BIN
assert/image-20240809145202119.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
assert/image-20240809150327849.png
Normal file
BIN
assert/image-20240809150327849.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
63
debuginros.md
Normal file
63
debuginros.md
Normal file
@ -0,0 +1,63 @@
|
||||
# 在Vscode中调试ROS
|
||||
|
||||
## 单节点应用
|
||||
|
||||
1. 在编译前在CMakeLists.txt文件中,指定Debug编译模式
|
||||
|
||||
```cmake
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
```
|
||||
|
||||
2. 配置launch.json 和tasks.json(在根目录.vscode文件夹中)
|
||||
|
||||
```json
|
||||
// tasks.json
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "rws build", // 名称自定义,要与launch.josn文件要一致 @1
|
||||
"type": "shell",
|
||||
"command": "source ${workspaceFolder}/install/setup.sh"
|
||||
// "command": "colcon build && source ${workspaceFolder}/install/setup.sh"
|
||||
// 不一定调试都需要重新编译
|
||||
},
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
//launch.json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug rws Executable", // 名称自定义
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/install/rws/lib/rws/rws_server", // 编译好的可执行程序所在路径
|
||||
"cwd": "${workspaceFolder}", // 工作目录,默认即可
|
||||
"args": [ // 调试阶段需要传递给可执行程序的参数
|
||||
],
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "rws build", // 这里需要与上面的task.json的名称对应 @1
|
||||
"miDebuggerPath": "/usr/bin/gdb",
|
||||
"miDebuggerArgs": "",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
3. 调试
|
||||
|
||||
![image-20240924145117137](/assert/1.png)
|
119
ffigen.md
Normal file
119
ffigen.md
Normal file
@ -0,0 +1,119 @@
|
||||
# ffigen
|
||||
|
||||
源文件代码如下
|
||||
|
||||
```c
|
||||
#ifndef HELLO_H
|
||||
#define HELLO_H
|
||||
#include "ppp.h" // 为了使用struct Point
|
||||
#include <stdio.h> // 标准库文件
|
||||
|
||||
void hello();
|
||||
void say_hello(const char* name);
|
||||
void say_hello2(struct Point* p);
|
||||
|
||||
|
||||
#endif
|
||||
```
|
||||
|
||||
只想生成当前文件下的函数声明,而不生成有关标准库里面的内容
|
||||
|
||||
```yaml
|
||||
# pubsspey.yaml
|
||||
headers:
|
||||
entry-points:
|
||||
- "clibrary/hello.h"
|
||||
include-directives:
|
||||
- "**hello.h" # 使用相对路径不管用
|
||||
|
||||
|
||||
```
|
||||
|
||||
生成出来的dart代码没有标准库中的符号。
|
||||
|
||||
但是自动生成ppp.h中有关struct Point 结构体的相关内容(say_hello2函数参数用到了)
|
||||
|
||||
```dart
|
||||
class Point extends ffi.Struct {
|
||||
@ffi.Int32()
|
||||
external int TID;
|
||||
@ffi.Int32()
|
||||
external int type;
|
||||
@ffi.Int32()
|
||||
......
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
如果不关心结构体具体内容
|
||||
|
||||
```yaml
|
||||
# pubsspey.yaml
|
||||
structs:
|
||||
dependency-only: opaque
|
||||
```
|
||||
|
||||
|
||||
|
||||
生成的代码如下
|
||||
|
||||
```dart
|
||||
class Point extends ffi.Opaque {} // error 需要手动修改
|
||||
// 修改后
|
||||
final class Point extends ffi.Opaque {}
|
||||
```
|
||||
|
||||
|
||||
|
||||
ffi生成的class 有错误 需要手动更改
|
||||
|
||||
```dart
|
||||
final class Point extends ffi.Struct {
|
||||
@ffi.Int32()
|
||||
external int x;
|
||||
} // 正确
|
||||
class Point extends ffi.Struct {
|
||||
@ffi.Int32()
|
||||
external int x;
|
||||
}// 错误,缺少final ffigen自动生成的
|
||||
```
|
||||
|
||||
未避免每次生成都需要手动更改
|
||||
解决方案:第一次通过ffi生成后,将class复制到另外一个文件中 bindings.dart。但是生成的dart代码中找不到Point类型,需要引入bindings.dart这个文件。于是需要进行配置,
|
||||
|
||||
使生成的代码,自动引入class所在的dart文件
|
||||
|
||||
```yaml
|
||||
library-imports:
|
||||
point: 'bindings.dart' # @1 point需要引入dart文件,也可以引入其他package bindings存放了class Point
|
||||
type-map:
|
||||
'structs': # Point是结构体.
|
||||
'Point': # 依赖的C语言中的结构体名称
|
||||
'lib': 'point' # @1 名字自定义
|
||||
'c-type': 'Point' # import 'bindings.dart' as point ffi.Pointer<point.Point> // point文件中具体要使用的类型
|
||||
'dart-type': 'point'
|
||||
```
|
||||
|
||||
```dart
|
||||
import 'bindings.dart' as point // @1;
|
||||
......
|
||||
|
||||
void say_hello2(
|
||||
ffi.Pointer<point.Point> p,
|
||||
) {
|
||||
return _say_hello2(
|
||||
p,
|
||||
);
|
||||
}
|
||||
|
||||
late final _say_hello2Ptr =
|
||||
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<point.Point>)>>(
|
||||
'say_hello2');
|
||||
late final _say_hello2 =
|
||||
_say_hello2Ptr.asFunction<void Function(ffi.Pointer<point.Point>)>();
|
||||
```
|
||||
|
||||
生成的代码中既没有错误的class Point 也不需要手动引入正确的dart Point类
|
||||
|
Loading…
Reference in New Issue
Block a user