You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows VS环境libcurl下载PNG返回CURLcode 23错误求助

问题原因

CURLcode 23 对应CURLE_WRITE_ERROR,触发条件非常明确:libcurl调用写入回调时,回调返回的实际写入字节数和传入的待写入字节数不匹配,就会直接中断请求返回这个错误。
你的代码在WSL环境正常、VS下Windows环境报错,基本逃不开两个原因:

  • 最核心的高频诱因:CRT运行库不匹配。Windows平台下FILE*指针对应的内部文件结构是和所属模块的C运行时(CRT)强绑定的,如果你自己VS工程配置的运行库选项(比如静态链接的/MT、/MTd)和你链接的libcurl库编译时用的运行库选项(比如动态链接的/MD、/MDd)不一致,libcurl内部调用默认的fwrite往你传的fp里写数据时,会因为跨CRT无法识别FILE结构直接写入失败,返回的写入字节数不符合预期,直接抛23错误。Linux环境下不存在这个CRT隔离的问题,所以同一份代码可以正常跑。
  • 代码逻辑漏判:你现在的逻辑在fopen返回NULL(文件打开失败,比如权限不足、路径非法)时,只打印了一行提示,没有做分支拦截,后续还是会把空指针传给CURLOPT_WRITEDATA,libcurl往空指针写数据必然失败,也会返回23。
修复方案
  1. 先对齐CRT运行库配置
    打开VS项目属性页,找到「C/C++ -> 代码生成 -> 运行库」选项,和你使用的libcurl版本的编译配置保持完全一致:
    • 如果用的是官方预编译的libcurl动态库(dll形式),Debug模式选多线程调试DLL (/MDd),Release模式选多线程DLL (/MD)
    • 如果是自己编译的静态libcurl,就选和你编译libcurl时完全相同的运行库选项
  2. 补全文件打开失败的拦截逻辑,打开失败直接走清理逻辑,不要继续执行curl请求
  3. 最稳妥的兜底方案:自己实现写入回调,彻底规避跨CRT的FILE*识别问题——回调函数在你自己的程序代码里执行,用的是当前工程的CRT,完全不会有跨模块识别问题。

修复后的可运行代码如下:

#include <stdio.h>
#include <curl/curl.h>

// 自定义写回调,逻辑和默认fwrite完全一致,但是在本工程内执行
static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp)
{
    size_t written = fwrite(contents, size, nmemb, (FILE*)userp);
    return written;
}

int main()
{
    char url[100] = "http://url_to.png"; // 替换为实际PNG地址
    CURL *curl = curl_easy_init();
    CURLcode res;
    FILE *fp = NULL;

    if (curl) {
        fp = fopen("./sample.png", "wb");
        if (fp == NULL) {
            printf("File cannot be opened\n");
            curl_easy_cleanup(curl);
            return 1;
        }

        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        // 建议加超时配置,避免异常场景下请求挂死
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);

        res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            printf("Cannot grab the image! Error Code: %d, error msg: %s\n",
                   res, curl_easy_strerror(res));
        }

        fclose(fp);
        curl_easy_cleanup(curl);
    }
    return 0;
}

补充说明:如果对齐CRT之后还是报错,检查下当前程序运行的工作目录是否有写入权限,部分情况下VS启动程序时的工作目录是项目根目录不是生成的exe所在目录,路径权限异常也可能导致写入失败。

内容的提问来源于stack exchange,提问作者Ignorant Potato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:24:30