在Go语言中调用C语言编写的DLL函数

在Go语言中调用C语言编写的DLL函数

本文详细阐述了在Go语言中调用C语言编写的动态链接库(DLL)函数的方法。主要介绍了两种核心途径:通过cgo实现Go与C代码的无缝集成,以及利用syscall包进行低级别、直接的DLL函数加载与调用。文章涵盖了两种方法的具体实现、代码示例、适用场景及注意事项,旨在为Go开发者提供在Windows平台上进行DLL互操作的实用指南。

在go语言的开发实践中,有时需要与已有的c语言库进行交互,特别是在windows平台,这意味着需要调用动态链接库(dll)中的函数。go语言提供了多种机制来实现这一目标,其中最常用且有效的是cgo工具和syscall包。

1. 使用 cgo 进行Go与C的互操作

cgo是Go语言提供的一个强大的工具,它允许Go程序直接调用C语言代码,反之亦然。对于调用C DLL中的函数,cgo提供了一种相对直接且集成度较高的方式,类似于C#中的DllImport。

工作原理:cgo通过在Go代码中嵌入C代码块,并利用Go的构建系统将Go代码和C代码一起编译。当Go程序需要调用DLL中的函数时,cgo会负责处理底层的链接和调用细节。

实现步骤:

引入C伪包: 在Go源文件中,通过import “C”语句引入C伪包。编写C代码或导入C头文件: 在import “C”语句上方,使用多行C注释块(/* … */)编写C代码,或者使用#cgo LDFLAGS等指令链接到外部DLL。调用C函数: 通过C.前缀来调用DLL中暴露的C函数。

示例代码(概念性):

立即学习“go语言免费学习笔记(深入)”;

假设有一个名为mydll.dll的DLL,其中包含一个C函数int MyDllFunc(int a, int b);。

package main/*#cgo LDFLAGS: -L. -lmy_dll // -L. 表示在当前目录查找DLL,-lmy_dll 表示链接 my_dll.lib 或 my_dll.dll#include  // 包含Windows头文件,如果DLL函数需要Windows API类型// 声明DLL中的函数,Go会通过链接器找到它extern int MyDllFunc(int a, int b);*/import "C" // 导入C伪包import "fmt"func main() {    // 调用DLL中的MyDllFunc函数    result := C.MyDllFunc(C.int(10), C.int(20))    fmt.Printf("Result from MyDllFunc: %dn", result)    // 如果DLL函数返回指针或复杂结构,需要进行Go与C类型转换    // 例如:C.GoString(C.char_ptr)}

注意事项:

编译环境: 使用cgo需要本地安装C/C++编译器(如MinGW-w64)。类型转换: Go类型和C类型之间需要进行显式转换(例如GoInt到C.int,或C.char到GoByte)。内存管理: 如果DLL函数涉及内存分配,需要特别注意内存的生命周期和所有权,避免内存泄漏。链接库: LDFLAGS指令用于指定DLL的路径和名称,通常是.lib文件或直接链接到.dll。

2. 使用 syscall 包进行低级别DLL调用

syscall包提供了Go程序与底层操作系统进行交互的能力,包括加载动态链接库和获取函数地址。这种方法更加底层,不需要C编译器,但相对来说代码会更复杂,需要手动处理函数签名和参数传递。

工作原理:syscall包允许程序在运行时动态加载DLL,并通过函数名获取DLL内部函数的内存地址。然后,可以使用syscall.Syscall、syscall.Syscall6等函数直接调用这些内存地址上的函数。

实现步骤:

加载DLL: 使用syscall.LoadLibrary函数加载指定的DLL文件。获取函数地址: 使用syscall.GetProcAddress函数获取DLL中特定函数的内存地址。调用函数: 使用syscall.Syscall系列函数(如Syscall, Syscall6, Syscall9等,根据参数数量选择)来调用获取到的函数地址。

示例代码:调用 kernel32.dll 中的 GetModuleHandleW 函数

package mainimport (    "fmt"    "syscall"    "unsafe" // 用于处理指针和类型转换)// 定义一个辅助函数用于错误处理func abort(funcName string, err syscall.Errno) {    fmt.Printf("Call %s failed: %vn", funcName, err)    // 实际应用中可能需要更复杂的错误处理,例如panic或返回error}func main() {    // 1. 加载 kernel32.dll    kernel32, err := syscall.LoadLibrary("kernel32.dll")    if err != nil {        abort("LoadLibrary kernel32.dll", err.(syscall.Errno))        return    }    defer syscall.FreeLibrary(kernel32) // 确保DLL在程序退出时被释放    // 2. 获取 GetModuleHandleW 函数的地址    // GetModuleHandleW 的 C 签名通常是 HMODULE GetModuleHandleW(LPCWSTR lpModuleName);    // 在Go中,我们通常传递0来获取当前进程的模块句柄    getModuleHandleW, err := syscall.GetProcAddress(kernel32, "GetModuleHandleW")    if err != nil {        abort("GetProcAddress GetModuleHandleW", err.(syscall.Errno))        return    }    // 3. 调用 GetModuleHandleW 函数    // GetModuleHandleW 只有一个参数 (lpModuleName),我们传递0表示NULL    // Syscall 函数的参数依次是:函数地址,参数数量,参数1,参数2,参数3...    // 返回值:ret (uintptr), _, callErr (syscall.Errno)    var nargs uintptr = 1 // GetModuleHandleW 接收一个参数    ret, _, callErr := syscall.Syscall(getModuleHandleW, nargs, 0, 0, 0) // 第一个0是lpModuleName,后两个0是Syscall的未使用参数    if callErr != 0 { // 检查Syscall返回的错误        abort("Call GetModuleHandleW", callErr)        return    }    // ret 即为 GetModuleHandleW 返回的模块句柄 (HMODULE)    moduleHandle := uintptr(ret)    fmt.Printf("Current module handle: 0x%Xn", moduleHandle)    // 另一个例子:调用 MessageBoxW (user32.dll)    // MessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);    user32, err := syscall.LoadLibrary("user32.dll")    if err != nil {        abort("LoadLibrary user32.dll", err.(syscall.Errno))        return    }    defer syscall.FreeLibrary(user32)    messageBoxW, err := syscall.GetProcAddress(user32, "MessageBoxW")    if err != nil {        abort("GetProcAddress MessageBoxW", err.(syscall.Errno))        return    }    // 准备参数    // 将Go字符串转换为UTF-16编码的C宽字符串    title := syscall.StringToUTF16Ptr("Go DLL Call")    message := syscall.StringToUTF16Ptr("Hello from Go via DLL!")    // MB_OK = 0x00000000L    // MB_ICONINFORMATION = 0x00000040L    // 组合起来就是 0x40    uType := uintptr(0x40) // MB_ICONINFORMATION    // 调用 MessageBoxW    // 参数顺序:hWnd, lpText, lpCaption, uType    // hWnd通常为0表示无父窗口    // 参数数量为4    ret, _, callErr = syscall.Syscall6(messageBoxW, 4, 0, uintptr(unsafe.Pointer(message)), uintptr(unsafe.Pointer(title)), uType, 0, 0)    if callErr != 0 {        abort("Call MessageBoxW", callErr)        return    }    fmt.Printf("MessageBoxW returned: %dn", ret)}

注意事项:

参数数量: syscall.Syscall用于0-3个参数的函数,syscall.Syscall6用于4-6个参数,syscall.Syscall9用于7-9个参数。对于更多参数的函数,可能需要自定义封装或结构体。类型映射: Go的基本类型需要手动转换为uintptr,字符串需要转换为UTF-16编码的指针(syscall.StringToUTF16Ptr)。错误处理: syscall.Syscall返回的第三个值callErr是一个syscall.Errno类型,用于指示系统调用是否成功。内存管理: 对于从DLL返回的指针,需要自行管理其生命周期,例如使用syscall.FreeHGlobal等函数释放由DLL分配的内存。

3. 选择合适的方法

cgo:优点: 语法更接近C语言,类型转换相对直观,可以利用C头文件进行函数声明,适合Go与C代码紧密集成、需要大量调用C库的场景。缺点: 需要安装C/C++编译器,编译过程相对复杂,可能增加编译时间,跨平台编译时需要注意C代码的兼容性。syscall:优点: 不需要C编译器,纯Go代码实现,可以在运行时动态加载DLL,提供更细粒度的控制,适合只调用少量DLL函数或不希望引入C编译依赖的场景。缺点: 代码相对冗长,需要手动处理所有参数的类型转换和内存管理,对DLL函数的C签名有严格的理解要求,错误处理可能更复杂。

总结

Go语言提供了cgo和syscall两种主要方式来调用C语言编写的DLL函数。cgo适用于Go与C代码紧密结合的场景,提供更高级别的抽象和更简单的函数调用语法,但依赖于C编译器。syscall包则提供了更底层的控制,允许在运行时动态加载DLL和调用函数,无需C编译器,但要求开发者对DLL函数的签名和参数传递有深入理解。根据项目的具体需求和对编译环境的依赖程度,可以选择最适合的方法。对于Windows平台DLL互操作的更多细节,可以参考Go官方的Wiki页面:https://www.php.cn/link/426281d73409354c214025722c6160a8。

以上就是在Go语言中调用C语言编写的DLL函数的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1398144.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
Golang并发编程有哪些最佳实践 总结性能优化与资源管理经验
上一篇 2025年12月15日 15:15:03
Go语言中调用C语言编写的DLL函数:Cgo与Syscall实践指南
下一篇 2025年12月15日 15:15:17

相关推荐

  • 如何提高公众号文章转发率_提升公众号文章转发率的实用方法

    如何提高公众号文章转发率_提升公众号文章转发率的实用方法如何提高公众号文章转发率_提升公众号文章转发率的实用方法如何提高公众号文章转发率_提升公众号文章转发率的实用方法如何提高公众号文章转发率_提升公众号文章转发率的实用方法

    提升公众号文章转发率需从标题、内容、激励、情感和排版五方面入手。一、设计含数字、情绪词和价值暗示的标题,并进行A/B测试;二、提供实用模板、步骤化指南和收藏提示,增强内容可分享性;三、设置转发抽奖、解锁资料、排行榜等社交激励机制;四、融入真实故事、群体认同金句和热点情感元素引发共鸣;五、优化视觉引导…

    2026年9月26日 • 用户投稿
    000
  • yandex引擎入口无需登录进入网站地址

    yandex引擎入口无需登录进入网站地址yandex引擎入口无需登录进入网站地址yandex引擎入口无需登录进入网站地址yandex引擎入口无需登录进入网站地址

    Yandex引擎无需登录的直接访问地址是https://yandex.com/,该网站提供高效精准的搜索体验,支持多语言检索,尤其擅长俄语及东欧、中亚地区语言处理,具备本地化信息匹配能力,并集成图片、视频、新闻、地图等垂直分类功能;用户无需注册即可使用全部基础服务,包括文本、语音和图像搜索,个性化设…

    2026年9月26日 • 用户投稿
    000
  • MSITitan游戏本修复蓝屏代码0x000000A0的完整教程。

    MSITitan游戏本修复蓝屏代码0x000000A0的完整教程。MSITitan游戏本修复蓝屏代码0x000000A0的完整教程。MSITitan游戏本修复蓝屏代码0x000000A0的完整教程。MSITitan游戏本修复蓝屏代码0x000000A0的完整教程。

    蓝屏代码0x000000A0通常由驱动冲突、系统文件损坏或硬件问题引起,可尝试更新或回滚驱动程序,运行SFC扫描修复系统文件,更新BIOS固件,禁用快速启动,以及排查外接设备兼容性来解决。 如果您的MSITitan游戏本在运行过程中频繁出现蓝屏,并显示错误代码0x000000A0,这通常意味着系统在…

    2026年9月26日 • 用户投稿
    000
  • Debian邮件服务器SSL证书安装方法

    在debian邮件服务器上安装ssl证书的步骤如下: 1. 安装OpenSSL工具包 首先,确保你的系统上已经安装了OpenSSL工具包。如果没有安装,可以使用以下命令进行安装: sudo apt-get updatesudo apt-get install openssl 2. 生成私钥和证书请求…

    2026年9月26日
    100
  • windows照片应用打不开怎么办 windows照片应用打不开的修复方法

    windows照片应用打不开怎么办 windows照片应用打不开的修复方法windows照片应用打不开怎么办 windows照片应用打不开的修复方法windows照片应用打不开怎么办 windows照片应用打不开的修复方法windows照片应用打不开怎么办 windows照片应用打不开的修复方法

    首先重启照片应用并结束相关进程,若无效则通过“应用和功能”修复或重置;仍无法解决时使用PowerShell重新安装应用,同时可运行系统故障排除工具检测问题;最后检查用户权限,创建新账户测试以排除配置损坏可能。 如果您尝试打开Windows照片应用时遇到无法启动或闪退的问题,可能是由于应用缓存损坏、系…

    2026年9月26日 • 用户投稿
    100
  • 多模态AI如何识别特殊符号 多模态AI符号理解能力解析

    多模态AI如何识别特殊符号 多模态AI符号理解能力解析多模态AI如何识别特殊符号 多模态AI符号理解能力解析多模态AI如何识别特殊符号 多模态AI符号理解能力解析多模态AI如何识别特殊符号 多模态AI符号理解能力解析

    多模态ai理解特殊符号主要依靠数据训练与上下文分析。首先,它通过大规模标注数据学习符号在不同场景中的常见用法,例如社交媒体中的“@”或“#”;其次,结合图像和文本的上下文进行语义推理,判断如“$”是货币单位还是情绪表达;最后,借助ocr与视觉特征识别图像中的符号,并通过跨模态联合建模提升准确性。 ☞…

    2026年9月26日 • 用户投稿
    800
  • sublime怎么格式化less文件_sublime LESS文件美化方法

    sublime怎么格式化less文件_sublime LESS文件美化方法sublime怎么格式化less文件_sublime LESS文件美化方法sublime怎么格式化less文件_sublime LESS文件美化方法sublime怎么格式化less文件_sublime LESS文件美化方法

    使用插件可实现Sublime Text格式化LESS文件。1. 安装HTML-CSS-JS Prettify插件,通过命令面板搜索并安装;2. 确保文件语法设为Less;3. 配置Prettify支持Less,在用户设置中启用less_enable;4. 全选代码后右键选择Prettify Code…

    2026年9月26日 • 用户投稿
    000
  • 京东商户入驻后如何设置促销_京东商户促销活动设置方法及规则解析

    京东商户入驻后如何设置促销_京东商户促销活动设置方法及规则解析京东商户入驻后如何设置促销_京东商户促销活动设置方法及规则解析京东商户入驻后如何设置促销_京东商户促销活动设置方法及规则解析京东商户入驻后如何设置促销_京东商户促销活动设置方法及规则解析

    首先进入京麦商家工作台营销中心创建促销活动,选择满减、满件打折等合适类型,按规则设置阶梯优惠与商品参与范围,定向人群及推广链接后提交审核,确保活动按时上线并监控展示效果。 如果您希望在京东平台提升商品销量和店铺曝光,合理的促销活动设置是关键环节。京东为商户提供了多样化的促销工具,但需遵循特定的规则和…

    2026年9月26日 • 用户投稿
    000
  • 剪映pc版怎么裁剪画面_剪映PC版视频画面裁剪教程

    剪映pc版怎么裁剪画面_剪映PC版视频画面裁剪教程剪映pc版怎么裁剪画面_剪映PC版视频画面裁剪教程剪映pc版怎么裁剪画面_剪映PC版视频画面裁剪教程剪映pc版怎么裁剪画面_剪映PC版视频画面裁剪教程

    剪映PC版支持通过基础裁剪、关键帧动态裁剪及缩放位移组合实现画面比例调整与区域去除。首先导入视频并拖入轨道,进入“画面”选项点击“裁剪”,可选择预设比例或自由调节;需动态裁剪时,在时间轴设置起始关键帧,移动播放头后调整裁剪框,系统自动记录变化;精细控制则结合“等比缩放”与“X/Y轴偏移”,配合关键帧…

    2026年9月26日 • 用户投稿
    000
  • 俄版搜索引擊主页yandex入口 俄罗斯浏览器搜索引擎入口yandex链接

    俄版搜索引擊主页yandex入口 俄罗斯浏览器搜索引擎入口yandex链接俄版搜索引擊主页yandex入口 俄罗斯浏览器搜索引擎入口yandex链接俄版搜索引擊主页yandex入口 俄罗斯浏览器搜索引擎入口yandex链接俄版搜索引擊主页yandex入口 俄罗斯浏览器搜索引擎入口yandex链接

    Yandex,被誉为“俄罗斯的谷歌”,是该国最大的互联网技术公司和搜索引擎。本文将为您清晰介绍Yandex的主要官方入口链接,并简要说明其核心功能,帮助您快速了解和使用这个强大的信息工具。 一、Yandex是什么? 1、立即进入“☞☞☞☞点击俄版搜索引擊主页yandex入口☜☜☜☜”; 2、立即进入…

    2026年9月26日 • 用户投稿
    000
  • 英特尔 NUC 主机程序崩溃?三星 SSD 主控老化掉速诊断​

    英特尔 NUC 主机程序崩溃?三星 SSD 主控老化掉速诊断​英特尔 NUC 主机程序崩溃?三星 SSD 主控老化掉速诊断​英特尔 NUC 主机程序崩溃?三星 SSD 主控老化掉速诊断​英特尔 NUC 主机程序崩溃?三星 SSD 主控老化掉速诊断​

    英特尔 nuc 主机程序崩溃,很可能是三星 ssd 主控老化掉速引起。1. 通过检查系统日志查看是否有磁盘错误信息;2. 使用 crystaldiskinfo 等工具读取 smart 信息判断 ssd 健康状态;3. 尝试更换 ssd 验证是否为原 ssd 问题。若确认为 ssd 老化掉速,可优化 …

    2026年9月26日 • 用户投稿
    000
  • NVIDIA RTX 4090是不是性能过剩了?

    RTX 4090是否性能过剩取决于用途:1. 游戏方面,在主流游戏如《守望先锋2》《赛博朋克2077》中性能明显溢出,多数玩家难以用满其能力;2. 生产力领域,凭借24GB显存和强大算力,它在AI训练、3D渲染等任务中仍具价值;3. 技术体验上,DLSS 3、Reflex等技术提供低延迟与未来兼容性…

    2026年9月26日
    1200
  • Debian OpenSSL如何进行数字签名验证

    在debian系统上使用openssl进行数字签名验证,可以按照以下步骤操作: 准备工作 安装OpenSSL:确保你的Debian系统已经安装了OpenSSL。如果没有安装,可以使用以下命令进行安装: sudo apt updatesudo apt install openssl 获取公钥:数字签名…

    2026年9月26日
    600
  • Claude是否能用于编写剧本 AI生成剧情内容的能力与使用体验

    Claude是否能用于编写剧本 AI生成剧情内容的能力与使用体验Claude是否能用于编写剧本 AI生成剧情内容的能力与使用体验Claude是否能用于编写剧本 AI生成剧情内容的能力与使用体验Claude是否能用于编写剧本 AI生成剧情内容的能力与使用体验

    本文将围绕利用AI工具进行剧本创作这一问题展开探讨。文章会首先介绍AI在剧情生成方面的核心能力,接着通过详细的步骤讲解,指导用户如何借助AI工具进行剧本的构思、撰写与优化,从而让用户了解整个操作流程。最后,会结合实际使用体验,分析其在创作过程中的优势与需要注意的方面,帮助创作者更有效地利用这一技术。…

    2026年9月26日 • 用户投稿
    700
  • windows卡在欢迎界面怎么办_Windows卡在欢迎界面无法进入系统解决方法

    windows卡在欢迎界面怎么办_Windows卡在欢迎界面无法进入系统解决方法windows卡在欢迎界面怎么办_Windows卡在欢迎界面无法进入系统解决方法windows卡在欢迎界面怎么办_Windows卡在欢迎界面无法进入系统解决方法windows卡在欢迎界面怎么办_Windows卡在欢迎界面无法进入系统解决方法

    强制重启进入安全模式排查问题,确认是否因第三方程序导致;2. 创建新用户账户以绕过损坏的配置文件;3. 禁用非必要启动项和服务释放系统资源;4. 使用sfc和DISM命令修复系统文件与镜像;5. 卸载最近更新或驱动解决兼容性问题,最终恢复系统正常登录。 如果您在启动Windows系统时,发现设备长时…

    2026年9月26日 • 用户投稿
    200
  • 外星人电脑无声音?声卡、音频接口故障检测方法​

    外星人电脑无声音?声卡、音频接口故障检测方法​外星人电脑无声音?声卡、音频接口故障检测方法​外星人电脑无声音?声卡、音频接口故障检测方法​外星人电脑无声音?声卡、音频接口故障检测方法​

    外星人电脑没声音的解决方法如下:1.检查音量是否静音,确认任务栏音量未设为最低或被划掉;2.排查驱动问题,通过设备管理器更新“声音、视频和游戏控制器”中的声卡驱动,或去官网下载最新驱动;3.排除外接设备故障,尝试更换耳机、音箱或usb接口;4.进入bios检查声卡是否被禁用,并调整设置;5.检查wi…

    2026年9月26日 • 用户投稿
    600
  • ChatGPT是否支持协同编辑 聊天过程中多人编辑的使用方式探讨

    ChatGPT是否支持协同编辑 聊天过程中多人编辑的使用方式探讨ChatGPT是否支持协同编辑 聊天过程中多人编辑的使用方式探讨ChatGPT是否支持协同编辑 聊天过程中多人编辑的使用方式探讨ChatGPT是否支持协同编辑 聊天过程中多人编辑的使用方式探讨

    关于ChatGPT是否支持多人协同编辑的问题,目前的答案是其本身不具备原生的实时协同功能。然而,这并不意味着无法实现多人协作。本文将通过一种结构化的角色扮演方法,详细讲解如何在一个聊天会话中模拟多人编辑与讨论的场景,让您清晰地掌握具体的操作流程,从而有效地利用ChatGPT进行团队协作。 ☞☞☞AI…

    2026年9月26日 • 用户投稿
    000
  • win8电脑自动重启是什么原因_Win8自动重启原因及修复

    win8电脑自动重启是什么原因_Win8自动重启原因及修复win8电脑自动重启是什么原因_Win8自动重启原因及修复win8电脑自动重启是什么原因_Win8自动重启原因及修复win8电脑自动重启是什么原因_Win8自动重启原因及修复

    答案:Windows 8电脑无故重启主因是系统崩溃、硬件故障或软件冲突。应先关闭“系统失败时自动重启”以查看蓝屏代码,再更新驱动、运行SFC扫描修复系统文件,排查内存、散热及电源问题,并进行病毒查杀。 如果您发现Windows 8电脑在使用过程中无故自动重启,这通常是由系统崩溃、硬件故障或软件冲突引…

    2026年9月26日 • 用户投稿
    000
  • yandex搜索引擎入口地址 yandex网页入口引擎直达

    yandex搜索引擎入口地址 yandex网页入口引擎直达yandex搜索引擎入口地址 yandex网页入口引擎直达yandex搜索引擎入口地址 yandex网页入口引擎直达yandex搜索引擎入口地址 yandex网页入口引擎直达

    Yandex作为一款功能强大的搜索引擎,尤其在图像搜索和东欧语系内容方面表现出色,是许多用户的优选工具。本文将为您提供Yandex网页版的核心入口地址,并解析不同入口的特点,帮助您根据需求快速、直接地访问。 1、立即进入“☞☞☞☞点击yandex搜索引擎入口地址☜☜☜☜”; 2、立即进入“☞☞☞☞点…

    2026年9月26日 • 用户投稿
    000
  • 《流放之路2》国服98元起 9月11日开启不删档测试

    《流放之路2》国服98元起 9月11日开启不删档测试《流放之路2》国服98元起 9月11日开启不删档测试《流放之路2》国服98元起 9月11日开启不删档测试《流放之路2》国服98元起 9月11日开启不删档测试

    《流放之路2》国服名为《流放之路:降临》,定价从98元起,豪华版分为四个档次,价格区间为198元至798元,另有典藏版售价2888元。目前游戏已在腾讯wegame平台开启预购,国服预充值不删档测试定于2025年9月11日正式开启! 98元“基础创始人资格包”包含9800点券、测试资格以及数字原声带。…

    2026年9月26日 • 用户投稿
    400

发表回复

登录后才能评论
关注微信