关于“ can not find ./obj/local/armeabi/libopencv_contrib.a: Permission denied ”问题

本文介绍了一个关于在Windows 7上使用Android NDK和OpenCV时遇到的文件权限问题及其解决方案。作者尝试运行NDK时遇到了无法访问特定OpenCV库文件的错误,并通过调整文件权限成功解决了该问题。

I am new to Android NDK and I have to use OpenCV in Android.

I tried to ran the NDK ahead , but these errors happened. Maybe I have no permission to use the file" /obj/local/armeabi/libopencv_contrib.a",How can I get the permission? And can the next error be OK when the first error is solved? My workspace OS is Windows7.

翻译:我是一个使用Android NDK的新手,而且我必须在android上面使用OpenCV开发包。


我试图跑NDK,但下面这些错误发生。也许我没有权限来使用文件“/ obj / local / armeabi / libopencv_contrib.a。 “,我怎样才能得到许可呢?并且可以接下来的错误可以当第一个错误是解决吗?我的工作空间是操作系统Windows7。

错误:$ NDK-build

SharedLibrary : libImgFun.so D:/Android/android-ndk-r7b-windows/android-ndk-r7b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.exe: ./obj/local/armeabi/libopencv_contrib.a: No such file: Permission denied

collect2: ld returned 1 exit status /cygdrive/d/Android/android-ndk-r7b-windows/android-ndk-r7b/build/core/build-binary.mk:314: recipe for target `obj/local/armeabi/libImgFun.so' failed make: *[obj/local/armeabi/libImgFun.so] Error 1

答案:

I had the same problem on Windows 7. I was able to just use chmod to set the permissions manually, and then it worked. My best guess is that this is a bug with how Cygwin, Windows, and the build process interact.

翻译:

我有相同的问题在Windows 7。我可以只使用chmod来手动设置权限,然后它的工作。我最好的猜测是,这是一个bug与Cygwin,Windows,构建过程交互。

  • Open a console window
  • > bash
  • > cd /cygdrive/<driveletter>/<wherever your project is>/obj/local/armeabi
  • > chmod 777 ./*

  • 翻译:打开Cygwin
  • 输入:cd /cygdrive/放工程文件的盘符/工程文件目录/obj/local/armeabi
  • 输入:chmod 777 ./*
  • (注:上面的错误的结果是没有生成libs文件,但生成了obj文件,因此改这个错误的时候obj不要删)
把子类NstStatusMonitor的cpp和h,单独拿出来用g++ -o NstStatusMonitor -I/opt/CIAP/include -L/opt/CIAP/lib -liap_NOS_Pool_ main.cpp NstStatusMonitor.cpp NstStatusMonitor.h可以编译成功,但是,直接在项目make报错 g++ -ggdb -Wall -DIAP_DB_MYSQL -DIAP_DB_SQLSERVER -DCIFXDN -fPIC -fpermissive -w -DIAP_RTOS -DVERSION_INFO=\"1.1.0\" ./src/standardTM.cpp ./obj/Aligner/NstAligner.o ./obj/Aligner/NstFuncAligner.o ./obj/Aligner/NstPhyAligner.o ./obj/Base/Monitor/NstGuardAction.o ./obj/Base/Monitor/NstCheckItem.o ./obj/Base/Monitor/NstAppDataLogMonitor.o ./obj/Base/Monitor/NstSInterlock.o ./obj/Base/Monitor/NstStatusMonitor.o ./obj/Base/Monitor/NstVInterlock.o ./obj/Base/Alarm/NstClearAlarmIncident.o ./obj/Base/Alarm/NstAlarmParser.o ./obj/Base/Alarm/NstAlarmObserver.o ./obj/Base/Module/NstAppService.o ./obj/Base/Module/NstFunctionalModel.o ./obj/Base/Module/NstMaintainModel.o ./obj/Base/Module/NstOperationalProcess.o ./obj/Base/Module/NstStation.o ./obj/Base/Module/NstChamber.o ./obj/Base/Module/NstEtchTMPlatform.o ./obj/Base/Module/NstBuffer.o ./obj/Base/Module/NstRorChecker.o ./obj/Base/Module/NstOperationalModel.o ./obj/Base/Module/NstModule.o ./obj/Base/Module/NstControlObjectEX.o ./obj/Base/Module/NstSimulatePM.o ./obj/Base/Util/NstNumberArrayTool.o ./obj/Base/Util/NstVirtualButton.o ./obj/Base/Util/NstVersion.o ./obj/Base/Util/NstAlarmTool.o ./obj/Base/Util/NstAliasExport.o ./obj/Base/Util/NstXmlGetter.o ./obj/Base/Util/NstTimeDiff.o ./obj/Base/Util/NstHeartBeatMachine.o ./obj/Base/Util/NstConditionUtil.o ./obj/Base/Util/NstUtil.o ./obj/Base/Util/NstStrTool.o ./obj/Base/Util/NstMapTool.o ./obj/Base/Util/NstPressureCondition.o ./obj/Base/Util/NstCTCExport.o ./obj/Base/Util/NstTimeSynchronizer.o ./obj/Base/Util/NstPressureValue.o ./obj/Base/Util/NstAutoLoad.o ./obj/Base/Util/NstTimeConsumeManager.o ./obj/Base/Util/NstCounterTimer.o ./obj/Base/Util/NstMathTool.o ./obj/Base/Util/NstUTime.o ./obj/Base/Util/NstAsyncCommConfig.o ./obj/Base/Util/NstEventLogger.o ./obj/Base/Util/NstHex.o ./obj/Base/Util/NstVirtualResetButton.o ./obj/Base/Exception/NstConfigException.o ./obj/Base/Exception/NstTMCException.o ./obj/Base/Process/NstAppRcpBody.o ./obj/Base/Process/NstProcessLogger.o ./obj/Base/Process/NstProcessChamber.o ./obj/Base/Process/NstProcessMonitor.o ./obj/Base/Process/NstProcessRecovery.o ./obj/Base/Process/NstTransRecovery.o ./obj/Base/Process/NstAppRcpStep.o ./obj/Base/Process/NstTransferChamber.o ./obj/Counter/NstGasCounter.o ./obj/Counter/NstLiterTorrCounter.o ./obj/Counter/NstRorCounter.o ./obj/Counter/NstLifeRatioCalculator.o ./obj/Counter/NstMaterialCounter.o ./obj/Counter/NstDeviceStatusCounter.o ./obj/EtchAdaptor/LoadLock/NstEtchMaintHeaterLoadLock.o ./obj/EtchAdaptor/LoadLock/NstEtchOprHeaterLoadLock.o ./obj/EtchAdaptor/LoadLock/NstEtchMaintLoadLock.o ./obj/EtchAdaptor/LoadLock/NstEtchMaintLoadLockVacSys.o ./obj/EtchAdaptor/LoadLock/NstEtchMaintHeaterLoadLockVacSys.o ./obj/EtchAdaptor/LoadLock/NstEtchFuncLoadLock.o ./obj/EtchAdaptor/LoadLock/NstEtchOprLoadLock.o ./obj/EtchAdaptor/LoadLock/NstEtchFuncHeaterLoadLock.o ./obj/EtchAdaptor/Vacuum/NstEtchVacuumSystem.o ./obj/EtchAdaptor/LoadLockProcess/NstEtchMotorPin.o ./obj/EtchAdaptor/LoadLockProcess/NstEtchLoadLock.o ./obj/EtchAdaptor/LoadPort/NstEtchMaintLoadPort.o ./obj/EtchAdaptor/LoadPort/NstEtchOprLoadPort.o ./obj/EtchAdaptor/LoadPort/NstEtchLoadPortDoor.o ./obj/EtchAdaptor/Chamber/NstEtchMaintVacSys.o ./obj/EtchAdaptor/Chamber/NstEtchOperationalBuffer.o ./obj/EtchAdaptor/Aligner/NstEtchMaintAligner.o ./obj/EtchAdaptor/Aligner/NstEtchOprAligner.o ./obj/EtchAdaptor/Robot/NstEtchOprVacRobot.o ./obj/EtchAdaptor/Robot/NstEtchOprRobot.o ./obj/EtchAdaptor/Robot/NstEtchMaintRobot.o ./obj/EtchAdaptor/Heater/NstLLHeaterProcessResource.o ./obj/EtchAdaptor/Heater/NstHeaterProcessResource.o ./obj/IOBridge/Ethercat/NstEtherCatCIFX.o ./obj/IOBridge/Ethercat/NstEtherCatPLC.o ./obj/IOBridge/Ethercat/NstEtherCatBaseDevice.o ./obj/IOBridge/Ethercat/NstEtherCat.o ./obj/IOBridge/PLC_Reserve/NstMotorPlc.o ./obj/IOBridge/PLC_Reserve/NstBeckhoffPlc.o ./obj/IOBridge/Robot/NstEthernetRobot.o ./obj/IOBridge/Base/NstSerialDevice.o ./obj/IOBridge/Base/NstEthernetSocket.o ./obj/IOBridge/EFEM/NstOcr.o ./obj/IOBridge/EFEM/NstEthernetLoadPort.o ./obj/IOBridge/EFEM/NstEthernetEFEM.o ./obj/IOBridge/Chiller/NstChiller.o ./obj/IOBridge/Chiller/NstModbusChiller.o ./obj/IOBridge/Chiller/NstChillerHRZ.o ./obj/IOBridge/Chiller/NstChillerHEC.o ./obj/IOBridge/TempCtl/NstModBusRTUTemplate.o ./obj/IOBridge/TempCtl/NstE5CTempCtl.o ./obj/IOBridge/Pump/NstCryoPump.o ./obj/LightTower/NstPhyLightTower.o ./obj/LightTower/NstLightTower.o ./obj/LightTower/NstPhyMALightTower.o ./obj/LoadLock/NstFuncLifter.o ./obj/LoadLock/NstPhyLifter.o ./obj/LoadLock/NstPhyPin.o ./obj/LoadLock/NstLoadLock.o ./obj/LoadLock/NstFuncHeater.o ./obj/LoadLock/NstPhyHeater.o ./obj/LoadLock/NstFuncChuck.o ./obj/LoadPort/NstOprLoadPort.o ./obj/LoadPort/NstPhyRorzeLoadPort.o ./obj/LoadPort/NstFuncLoadPort.o ./obj/LoadPort/NstPhyLoadPort.o ./obj/Robot/NstOprRobot.o ./obj/Robot/NstFuncRobot.o ./obj/Robot/NstTransOffsetAnalysis.o ./obj/Robot/NstPhyRobot.o ./obj/TempCtl/NstPhyTempControl.o ./obj/TempCtl/NstPhyChiller.o ./obj/TempCtl/NstFuncTempControl.o ./obj/Vacuum/NstFuncCryoPumpShi.o ./obj/Vacuum/NstPhyButterflyValve.o ./obj/Vacuum/NstVacuumSystem.o ./obj/Vacuum/NstPhyCryoPump.o ./obj/Vacuum/NstPhyFIBValve.o ./obj/Vacuum/NstPhyPC.o ./obj/Vacuum/NstPhyTurboPumpPF.o ./obj/Vacuum/NstPhyGauge.o ./obj/Vacuum/NstVacuumProcedure.o ./obj/Vacuum/NstFuncCryoPumpShiGroup.o ./obj/Vacuum/NstPhyMFC.o ./obj/Vacuum/NstPhyButterflyValveEC.o ./obj/Vacuum/NstFuncTurboPump.o ./obj/Vacuum/NstVacuumService.o ./obj/Vacuum/NstPhyValve.o ./obj/Vacuum/NstPhyPendulumValve.o ./obj/Vacuum/NstPhySlotValve.o ./obj/Vacuum/NstPhyDryPump.o ./obj/Vacuum/NstPhyPump.o ./obj/Vacuum/NstFuncCryoPump.o ./obj/Vacuum/NstPhyTurboPump.o ./obj/Vacuum/NstFuncRefill.o ./obj/Vacuum/NstPhyGateValve.o -I./src/Aligner -I./src/Base -I./src/Base/Enum -I./src/Base/Monitor -I./src/Base/Alarm -I./src/Base/Module -I./src/Base/Util -I./src/Base/Exception -I./src/Base/Process -I./src/Counter -I./src/EtchAdaptor -I./src/EtchAdaptor/LoadLock -I./src/EtchAdaptor/Vacuum -I./src/EtchAdaptor/LoadLockProcess -I./src/EtchAdaptor/LoadPort -I./src/EtchAdaptor/Chamber -I./src/EtchAdaptor/Aligner -I./src/EtchAdaptor/Robot -I./src/EtchAdaptor/Heater -I./src/IOBridge -I./src/IOBridge/Ethercat -I./src/IOBridge/PLC_Reserve -I./src/IOBridge/Robot -I./src/IOBridge/Base -I./src/IOBridge/EFEM -I./src/IOBridge/Chiller -I./src/IOBridge/TempCtl -I./src/IOBridge/Pump -I./src/LightTower -I./src/LoadLock -I./src/LoadPort -I./src/Robot -I./src/TempCtl -I./src/Vacuum/ -I/opt/CIAP/include -I/opt/Ice-3.1.4/include -I/usr/include -I/usr -I/opt/dnscan/include -I/usr/local/include/cifx -L/opt/CIAP/lib -liap_NOS_Pool_ -L/opt/Ice-3.1.4/lib -lIce -lIceUtil -lIceStorm -lmysqlpp -L/opt/dnscan/lib -ldnscan -lcurl -L/usr/local/lib -lcifx -lpciaccess -L/usr/lib -lxerces-c -o ./bin/debug/standardTM /usr/bin/ld: ./obj/Base/Monitor/NstStatusMonitor.o:(.data.rel.ro._ZTVN3Nst16NstStatusMonitorE[_ZTVN3Nst16NstStatusMonitorE]+0xe8): undefined reference to `non-virtual thunk to IAP::CONTROL::ControlMonitor::beginPostAlarm()' /usr/bin/ld: ./obj/Base/Monitor/NstStatusMonitor.o:(.data.rel.ro._ZTVN3Nst16NstStatusMonitorE[_ZTVN3Nst16NstStatusMonitorE]+0xf0): undefined reference to `non-virtual thunk to IAP::CONTROL::ControlMonitor::endPostAlarm()' /usr/bin/ld: ./obj/Base/Monitor/NstStatusMonitor.o:(.data.rel.ro._ZTVN3Nst16NstStatusMonitorE[_ZTVN3Nst16NstStatusMonitorE]+0x118): undefined reference to `non-virtual thunk to IAP::CONTROL::ControlMonitor::updateFromIncident(IAP::CONDITION::Incident*)' collect2: error: ld returned 1 exit status make: *** [Makefile:113: standardTM] Error 1
最新发布
08-22
<think>我们正在处理一个链接错误,错误信息指出在链接过程中找不到几个特定的非虚thunk符号。这些符号与`IAP::CONTROL::ControlMonitor`类的成员函数相关。错误发生在构建`NstStatusMonitor`对象时,具体是虚函数表(vtable)中的某些条目指向了未定义的thunk函数。 ### 错误原因分析 1. **非虚thunk(non-virtual thunk)**:通常出现在多重继承中,当派生类覆盖了基类的虚函数,并且需要调整`this`指针时,编译器会生成thunk函数。thunk是一个小代码片段,用于调整`this`指针(因为多重继承中基类的地址可能和派生类不同)并跳转到实际的函数实现。 2. **错误信息**: - `undefined reference to non-virtual thunk to IAP::CONTROL::ControlMonitor::beginPostAlarm()` - 类似地,还有`endPostAlarm`和`updateFromIncident`函数。 这表明在`NstStatusMonitor`类的虚函数表中,这些函数对应的条目指向了thunk函数,但链接器找不到这些thunk函数的实现。 3. **可能的原因**: - **未定义虚函数**:`IAP::CONTROL::ControlMonitor`类中声明的虚函数(如`beginPostAlarm`等)没有被实现(即没有定义)。 - **虚函数表未完全生成**:如果包含虚函数的类没有定义任何一个非内联的虚函数(尤其是虚析构函数),则可能导致虚函数表(vtable)没有被正确生成。 - **链接顺序问题**:如果实现这些函数的库在链接时被放在了错误的位置(比如在引用它的目标文件之前),则链接器可能找不到定义。 - **符号可见性问题**:如果这些函数在动态库中,并且没有正确导出,那么链接时也会找不到。 ### 解决方案步骤 #### 步骤1: 确保虚函数有定义 检查`IAP::CONTROL::ControlMonitor`类中声明的虚函数是否都有定义。特别是错误信息中提到的三个函数: - `beginPostAlarm()` - `endPostAlarm()` - `updateFromIncident(IAP::CONDITION::Incident*)` 如果这些函数是纯虚函数(在类声明中用`=0`标记),那么必须在派生类中实现它们。如果它们不是纯虚函数,那么必须在某个地方提供它们的实现(在基类或派生类中)。 例如,在基类中: ```cpp // ControlMonitor.h namespace IAP::CONTROL { class ControlMonitor { public: virtual void beginPostAlarm(); virtual void endPostAlarm(); virtual void updateFromIncident(CONDITION::Incident* incident); // ... 其他成员 ... }; } ``` 在源文件中实现(即使为空): ```cpp // ControlMonitor.cpp #include "ControlMonitor.h" namespace IAP::CONTROL { void ControlMonitor::beginPostAlarm() { // 实现,哪怕为空 } void ControlMonitor::endPostAlarm() { // 实现,哪怕为空 } void ControlMonitor::updateFromIncident(CONDITION::Incident* incident) { // 实现,哪怕为空 } } ``` #### 步骤2: 确保虚析构函数有定义 如果`ControlMonitor`类有虚析构函数(通常应该有),那么即使它是纯虚的,也必须提供定义。否则,会导致链接错误。 ```cpp // ControlMonitor.h class ControlMonitor { public: virtual ~ControlMonitor() = 0; // 纯虚析构函数声明 // ... }; ``` 在源文件中定义: ```cpp // ControlMonitor.cpp ControlMonitor::~ControlMonitor() { // 即使为空 } ``` #### 步骤3: 检查类定义的完整性 确保`NstStatusMonitor`类正确继承了`ControlMonitor`并覆盖了这些虚函数。同时,确保在`NstStatusMonitor`类中,这些覆盖函数的签名与基类完全一致。 例如: ```cpp // NstStatusMonitor.h #include "ControlMonitor.h" namespace Nst { class NstStatusMonitor : public IAP::CONTROL::ControlMonitor { public: void beginPostAlarm() override; void endPostAlarm() override; void updateFromIncident(IAP::CONDITION::Incident* incident) override; // ... }; } ``` 在`NstStatusMonitor`的源文件中实现这些函数: ```cpp // NstStatusMonitor.cpp #include "NstStatusMonitor.h" namespace Nst { void NstStatusMonitor::beginPostAlarm() { // 实现 } // 其他函数实现... } ``` #### 步骤4: 检查链接顺序 在Makefile中,确保包含`ControlMonitor`实现的源文件(如`ControlMonitor.cpp`)被编译并链接到最终的可执行文件中。同时,检查链接库的顺序,确保提供这些函数实现的库在引用它们的目标文件之后。 例如,在Makefile中: ```makefile # 错误的链接顺序:先链接包含实现的库,再链接使用它的目标文件 standardTM: main.o NstStatusMonitor.o libcontrol.a $(CXX) -o $@ $^ # 正确的链接顺序:将库放在使用它的目标文件之后 standardTM: main.o NstStatusMonitor.o $(CXX) -o $@ $^ -lcontrol ``` 或者如果`ControlMonitor`的实现就在同一个项目中,确保对应的源文件被编译: ```makefile OBJS = main.o NstStatusMonitor.o ControlMonitor.o standardTM: $(OBJS) $(CXX) -o $@ $^ ``` #### 步骤5: 检查符号可见性(如果使用动态库) 如果`ControlMonitor`类在动态库中,确保这些函数被正确导出。在Linux上,可以使用`__attribute__((visibility("default")))`来标记需要导出的类或函数。 例如,在类声明前: ```cpp class __attribute__((visibility("default"))) ControlMonitor { // ... }; ``` 或者在编译时使用`-fvisibility=hidden`和`-fvisibility-inlines-hidden`,然后显式导出需要的符号。 ### 调试工具 - 使用`nm`命令查找目标文件或库中的符号: ```bash nm -gC ./obj/Base/Monitor/ControlMonitor.o | grep beginPostAlarm ``` 检查是否输出了`beginPostAlarm`的符号(包括thunk符号)。如果找不到,说明没有定义。 - 使用`c++filt`来解析符号名: ```bash nm ./obj/Base/Monitor/NstStatusMonitor.o | c++filt | grep thunk ``` - 使用`objdump`查看目标文件的虚函数表: ```bash objdump -S -j .data.rel.ro ./obj/Base/Monitor/NstStatusMonitor.o ``` 查看虚函数表(vtable)的内容,确认其中引用的符号。 ### 总结 1. **确保所有虚函数(包括析构函数)都有定义**,即使它们是纯虚的(析构函数必须定义)。 2. **检查派生类是否正确覆盖基类虚函数**。 3. **验证链接顺序**,确保包含实现的库在链接命令中出现在使用它的目标文件之后。 4. **如果涉及动态库,检查符号导出**。 通过以上步骤,应该能够解决这个链接错误。 --- §§相关问题§§ 1. C++中虚函数表(vtable)的生成规则是什么? 2. 如何解决多重继承中的"diamond problem"? 3. C++动态库开发中如何正确管理符号可见性?</think>根据您提供的链接错误信息,问题出在`NstStatusMonitor`类与`IAP::CONTROL::ControlMonitor`基类的虚函数实现上。以下是系统化的解决方案: ### 问题根本原因 1. **thunk机制失效**:编译器需要生成`non-virtual thunk`代码调整`this`指针(多重继承场景) 2. **虚函数表不完整**:基类`IAP::CONTROL::ControlMonitor`的虚函数未正确定义 3. **符号可见性问题**:动态库中虚函数未正确导出(常见于跨库继承) ### 解决方案步骤 #### 1. 验证基类虚函数定义 在`ControlMonitor`头文件和源文件中确保: ```cpp // ControlMonitor.h namespace IAP::CONTROL { class ControlMonitor { public: virtual void beginPostAlarm() = 0; // 纯虚声明 virtual ~ControlMonitor(); // 虚析构必须定义! }; } // ControlMonitor.cpp IAP::CONTROL::ControlMonitor::~ControlMonitor() {} // 关键定义 ``` > 虚析构函数即使为空也必须定义,否则破坏vtable[^1] #### 2. 检查派生类实现 确认`NstStatusMonitor.cpp`实现所有纯虚函数: ```cpp // NstStatusMonitor.cpp void NstStatusMonitor::beginPostAlarm() { // 具体实现(不能为空) } void NstStatusMonitor::endPostAlarm() { // 具体实现 } void NstStatusMonitor::updateFromIncident(IAP::CONDITION::Incident* incident) { // 具体实现 } ``` #### 3. 调整链接顺序 在Makefile中确保派生类实现在基类之后链接: ```makefile # 修改前(错误) OBJS = NstStatusMonitor.o ControlMonitor.o # 修改后(正确) OBJS = ControlMonitor.o NstStatusMonitor.o ``` > 链接顺序:基类实现必须在派生类之前[^1] #### 4. 处理动态库符号导出(如适用) 若涉及动态库,添加可见性控制: ```cpp // 添加导出宏 #if defined(_WIN32) #define API_EXPORT __declspec(dllexport) #else #define API_EXPORT __attribute__((visibility("default"))) #endif class API_EXPORT ControlMonitor { ... }; ``` #### 5. 调试工具验证 ```bash # 检查符号定义 nm -gC obj/Base/Monitor/ControlMonitor.o | grep beginPostAlarm # 反汇编验证thunk objdump -d obj/Base/Monitor/NstStatusMonitor.o | c++filt | grep "thunk to" ``` ### 关键预防措施 1. **虚析构函数法则**:任何包含虚函数的类必须定义虚析构函数 2. **纯虚函数实现**:纯虚析构函数必须提供空实现 3. **多重继承检查**:使用`dynamic_cast`验证指针偏移: ```cpp ControlMonitor* monitor = new NstStatusMonitor(); assert(dynamic_cast<NstStatusMonitor*>(monitor)); // 验证指针有效性 ``` > 通过显式定义虚析构函数,可强制编译器生成完整vtable,解决90%的thunk相关问题[^1] ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值