如何在 C 中同时使用 GTK 和 libcurl?

J·特尼森

我正在尝试使用 GTK 为 GUI 开发一个 C 应用程序,libcurl 通过 Web API 和 cJSON 获取数据来解析 JSON。

我的问题是,当我在 gtk_init 之后使用 libcurl 执行我的请求时,我得到的数据无法在 JSON 中解析。否则,如果我在 gtk_init 之前获取数据并解析它,解析工作正常。

我有一个示例来演示它,主程序中的第一个 printf 正确返回 JSON,但 gtk_init 之后的第二个 printf 返回 NULL(准确地说,解析在第一个十进制数处停止并失败):

初始化字符串:

void initString(String * s) {
  s->len = 0;
  s->ptr = malloc(s->len + 1);
  if (s->ptr == NULL) {
    fprintf(stderr, "malloc() failed\n");
    exit(EXIT_FAILURE);
  }
  s->ptr[0] = '\0';
}

写函数:

size_t writeFunc(void *ptr, size_t size, size_t nmemb, String * s)
{
  size_t newLen = s->len + size*nmemb;
  s->ptr = realloc(s->ptr, newLen + 1);
  if (s->ptr == NULL) {
    fprintf(stderr, "realloc() failed\n");
    exit(EXIT_FAILURE);
  }
  memcpy(s->ptr + s->len, ptr, size * nmemb);
  s->ptr[newLen] = '\0';
  s->len = newLen;

  return size * nmemb;
}

我使用 libcurl 获取数据的函数:

char * getData(gpointer user_data)
{
curl_global_init(CURL_GLOBAL_ALL);
CURL * curl;
char * url = user_data;
CURLcode res;
String s;
struct curl_slist * headers = NULL;
curl = curl_easy_init();

if(curl)
{
    initString(&s);

    headers = curl_slist_append(headers, "Accept: application/json");
    headers = curl_slist_append(headers, "Content-Type: application/json");
    headers = curl_slist_append(headers, "charsets: utf-8");

    //curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl, CURLOPT_URL, url);

    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_easy_setopt(curl, CURLOPT_SSLVERSION, 6);

    curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    //write data in a string
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunc);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);

    res = curl_easy_perform(curl);
}

if(res != CURLE_OK)
  fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));

curl_easy_cleanup(curl);
return s.ptr;
}

主要的 :

int main(int argc, char ** argv)
{
char * str;
cJSON * json;

str = getData("https://data.culture.gouv.fr/api/records/1.0/search/?dataset=liste-et-localisation-des-musees-de-france&facet=ville&sort=ville&facet=nomdep&refine.nomdep=AIN&rows=1");
json = cJSON_Parse(str);
printf("DATA : %s\n", cJSON_Print(json));//returns the JSON perfectly

gtk_init(&argc,&argv);

str = getData("https://data.culture.gouv.fr/api/records/1.0/search/?dataset=liste-et-localisation-des-musees-de-france&facet=ville&sort=ville&facet=nomdep&refine.nomdep=AIN&rows=1");
json = cJSON_Parse(str);
printf("ERROR : %s\n", cJSON_GetErrorPtr());//returns half of data
printf("DATA : %s\n", cJSON_Print(json));//returns NULL

gtk_main();

curl_global_cleanup();

return EXIT_SUCCESS;
}

我试图通过使用 g_idle_add、gdk_threads_idle_add、gdk_threads_entry 和 gdk_threads_leave、pthread_create 和 pthread_join 创建线程来解决这个问题,但没有任何效果。

有人知道如何解决这个问题吗?

谢谢。

您需要缩小问题的范围。换句话说,您需要在MVCE 中使用“M” 目前你有三个库:

  • Gtk+
  • 卷曲
  • JSON

可能以任意方式进行交互。您需要检查的内容:

  • cURL 在gtk_init调用之前和之后返回不同的数据吗?如果不是,则问题不在于 cURL。

  • 如果您在程序中对 JSON 数据进行硬编码并使用 cJSON 对其进行解析,那么之前和之后的结果是否不同gtk_init如果是这样,问题出在 cJSON 中。如果不是,则问题与 cJSON 无关。


我的猜测如下。gtk_init做几件事,其中包括设置 locale由于您从.fr域中获取数据,因此我假设您在计算机上设置了法语区域设置。

准确地说,解析在第一个十进制数处停止并失败

在法语中,十进制分隔符是逗号,而不是句点.,所以我想在 GTK+ 更改语言环境后,cJSON 开始寻找,十进制数,但它找到.并失败了。

可能的解决方案

  • 作为解决方法,请gtk_disable_setlocalegtk_init. 这可能会导致意想不到的后果,例如。您的程序开始在其 UI 中以英语格式而不是法语显示数字。

  • 真正的解决方案是在 cJSON 中引发错误,因为 JSON 解析在解析数字时不应该考虑语言环境。JSON要求句点.作为小数点分隔符。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何同时安装libcurl3和libcurl4?

如何在 libcurl/c++ 中使用 curl_blob?

如何在C#中同时读取和写入文件

如何使用luacurl / libcurl / curl和Lua获取HTML代码

如何在GTK C中隐藏鼠标指针

如何在GTK + C中的回调之间进行通信

c++ - 如何使用glade和gtkmm C++重新绘制Gtk :: Image组件

如何在libcurl中设置代理授权

如何在 libcurl 中启用 rsync?

如何在 clion 中添加 libcurl

c ++ 14-如何在Windows中使用独立的libcurl库启用HTTP

如何在C ++中使用libcurl调试SSL连接错误(vs2013)

如何在此请求中使用 libcurl 并获得 json 服务器答案 c++?

如何将libcurl链接到Linux中的C ++程序?

如何创建Cairo Context以使用Gtk Sharp和C#绘制代码

在Windows中安装C ++的libcurl

如何在 sed 中同时使用 q 和 s 命令?

如何在MySQL中同时使用WHERE BETWEEN和WHERE?

如何在Spring Rest中同时使用@Pathvariable和@RequestParam

如何在MongoDB中同时使用findOne和聚合?

如何在 minimatch 模式中同时使用 NOT 和 OR 进行过滤?

困惑于如何在Java中同时使用索引和值

如何在管理菜单中同时使用 Resource 和 MenuItem

如何在MainActivity中同时使用AppBaseActivity和ActionBarActivity

如何在python中同时使用封装和继承

如何在Laravel 5中同时使用orderBy和Paginate

如何在Laravel中同时使用Web和API防护?

我如何在字符串中同时使用 $ 和 @?

如何在Laravel中同时使用get和分页