gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 07:49:25 24 4
gpt4 key购买 nike

我正在尝试用 C 语言开发一个应用程序,其中 GTK 用于 GUI,libcurl 用于通过 Web API 获取数据,cJSON 用于解析 JSON。

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

我有一个例子来演示它,main 中的第一个 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+
  • curl
  • cJSON

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

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

  • 如果您在程序中硬编码 JSON 数据并使用 cJSON 解析它,gtk_init 前后结果是否不同?如果是这样,问题出在 cJSON 中。如果不是,则问题与 cJSON 无关。


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

to be exact, the parsing stops at the first decimal number and fail

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

可能的解决方案

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

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

关于c - 如何在 C 中同时使用 GTK 和 libcurl?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54813715/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com