---
title: "动态链接库 程序编写实验"
description: "通过dlopen，从C++/Swift/Python/Go调用同一个动态链接库。"
date: 2026-05-27T22:49:20+08:00
image: 
math: 
license: 
hidden: false
comments: false
draft: false
slug: "00H"
---
（2026年5月27日补档，原始发布日期为2026年4月16日。）  
基于Apple Silicon平台的macOS测试。  
附上[完整项目目录](dynamic_library.zip)，内含源代码、编译脚本、测试脚本及二进制文件。
### 项目目录结构
```
dynamic_library
├── source
│   ├── cpp
│   │   ├── build.sh
│   │   └── cpp.cpp
│   ├── dylib
│   │   ├── build.sh
│   │   └── cpp_dylib.cpp
│   ├── go
│   │   ├── build.sh
│   │   └── go.go
│   ├── python
│   │   ├── build.sh
│   │   └── python.py
│   └── swift
│       ├── build.sh
│       └── swift.swift
├── cpp
├── go
├── libtesuto.dylib
├── python
├── swift
├── 编译可执行文件.sh
├── 测试.sh
└── 清空二进制文件.sh
```
- 每个语言文件夹下的`build.sh`会自动将对应语言的二进制文件生成在上两级目录，无需手动移动；
- `编译可执行文件.sh`实际上是把每个`build.sh`执行一遍；
- `测试.sh`可用于快捷测试各个语言程序的运行状况，还支持模拟`libtesuto.dylib`缺失的情况。
### 原理
`libtesuto.dylib`由`cpp_dylib.cpp`编译而来，里面定义了一个`int`函数，名称为`inout`，传递3个参数：  
- `input`：C风格字符串，只读，表示用户输入；
- `output`：C风格字符串，会进行修改，储存函数处理后的用户输入（实际上是在末尾加上`_modified`）；
- `outputSize`：无符号整数类型，表示`output`的长度（4种语言的程序中均指定为`1024`），用于给`strncpy`函数提供参数。  
该函数成功执行后，返回固定整数`803`。  
4种语言的程序均收集用户输入，然后通过`dlopen`（不过Python里面好像叫`CDLL`…）打开外部的动态链接库，调用`inout`函数，并通过各自的C ABI兼容方法实现传参，最后收集函数返回值并打印。