在独立应用程序或共享对象中使用时的不同行为

问题描述 投票:0回答:1

我正在为 Basex(XML 数据库)开发 C++ 客户端。其中一个函数用于在数据库中保存字符串、文件或 URL。此功能已在独立应用程序中进行测试。

void addRawInput(const std::string & Add) {
  std::vector<std::byte> newBytes;
  FILE* fileTest;
  bool isValid = false;

  wordexp_t exp_result;
  wordexp(Add.c_str(), &exp_result, 0); 
  const char * openTest = exp_result.we_wordv[0];

  fileTest = std::fopen( openTest, "r+");
  isValid  = isValidURL(Add.c_str());
  if (fileTest) { 
    int c;
    std::string readAdd;
    while ((c = std::fgetc(fileTest)) != EOF) { 
        readAdd.push_back(c); } 
    if (std::ferror(fileTest)) {
        std::puts("I/O error when reading");
    } else if (std::feof(fileTest)) {
        std::puts("End of file reached successfully");
        newBytes = getBytes( readAdd);                 // Convert readAdd to vector<std::byte>
    }
    std::fclose(fileTest);
  } else if (isValid) {                  // 'Add' is a URL
    try
    {   std::ostringstream result;
        curlpp::Cleanup cleaner;
        curlpp::Easy request;

        request.setOpt(curlpp::options::Url(Add));
        request.setOpt(new cURLpp::Options::WriteStream(&result));
        request.perform();
        cout << result.str() << endl;
    } catch(curlpp::RuntimeError & e) {
        std::cout << e.what() << std::endl;
    } catch(curlpp::LogicError & e) {
        std::cout << e.what() << std::endl;
    }
  } else {                                                   // 'Add' is a string
      newBytes = getBytes( Add);
  };
};

std::vector<std::byte> getBytes(std::string const &s){
    std::vector<std::byte> bytes;
    bytes.reserve(s.size());

    std::transform(std::begin(s), std::end(s), std::back_inserter(bytes), [](char c){
        return std::byte(c);
    });
    return bytes;
}

int main() {
    cout << "!!!Hello World!!!" << endl;
    addRawInput("https://raw.githubusercontent.com/BaseXdb/basex/master/basex-api/src/test/resources/first.xml");
    return 0;
}

输出:

!!!Hello World!!!
<first><title>First Document</title></first>

此功能添加到共享对象。我使用这个 CMakeLists.txt 来编译共享对象:

# Specify the minimum version.
cmake_minimum_required(VERSION 3.25.1)

# Specify the project info.
project(libBasexCpp VERSION 1.0 DESCRIPTION "LibBasexCpp  library")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_OBJCXX_STANDARD_REQUIRED ON)

include(FindPkgConfig)
pkg_check_modules(CURLPP REQUIRED curlpp)

# Declare the library target.
# file (GLOB_RECURSE SOURCES src/*.cpp)
# add_executable(libBasexTest ${SOURCES})

add_library(${PROJECT_NAME} SHARED
  # src/BasexSocket.h
  src/BasexClient.cpp
  src/BasexClient.h
)
target_link_libraries(${PROJECT_NAME} ${CURLPP_LDFLAGS})
# Configure the directories to search for header files.
target_include_directories(${PROJECT_NAME} PRIVATE src)
# Set the version property.
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION})
# Set the shared object version property to the project's major version.
set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR})
# Set the public header property to the one with the actual API.
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER   src/BasexClient.h)

# prevent 'lib' prefix
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "")

这个函数的签名是

    BasexClient& addRawInput(const std::string & App, std::vector<std::byte> &To);

添加以下两行后,实现版本遵循签名。

addVoid(newBytes, To); 
return *this;

从测试应用程序调用此函数时,没有输出。在 Eclipse CDT 中调试该代码也是不可能的。但是当我评论 URL 部分的行时,我收到正确的输出并且调试器照常工作。

我是 C++ 和使用 CMake 的新手。这种行为的原因可能是什么?

c++ cmake curlpp
1个回答
0
投票
  1. 以下几行导致错误:

    } else if (isValid) { // 'Add' 是一个 URL 尝试 { std::ostringstream 结果; curlpp::清理清洁器; curlpp::简单请求;

     request.setOpt(curlpp::options::Url(Add));
     request.setOpt(new cURLpp::Options::WriteStream(&result));
     request.perform();
     cout << result.str() << endl;
    

    } 捕捉(curlpp::RuntimeError & e){ 标准::计算<< e.what() << std::endl; } catch(curlpp::LogicError & e) { std::cout << e.what() << std::endl; }

  2. 我正在开发 2 个库——libBasexCpp 和 libBasexSocket。这些库和测试应用程序 (libBasexTest.cpp) 的源代码存储在 3 个 Eclipse CDT 项目中。而“真正的”测试只能在安装了 BaseX 后运行。

  3. 就在几分钟前,我从 Fedora 中读到一个“糟糕”的系统错误日志。此消息表明 libBasexTest 在 libBasexCpp 中引发了一般保护错误。这可能意味着错误的原因更为基本。我必须弄清楚如何调试它;-(

© www.soinside.com 2019 - 2024. All rights reserved.