رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران
  • 2
SeedPuller

نوشتن کلاس برای libcurl


سوال

سلام.

من داشتم برای تمرین سعی میکردم که یک کلاس برای libcurl بنویسم تا زمانی که میخوام از این کتابخونه استفاده کنم، صرفا یک شئ از کلاس خودم بسازم.

اما متاسفانه زمان اجرای تابع write_data،  برنامه segmentation fault می‌ده. خودم نتونستم مشکلش رو پیدا کنم. متشکر میشم اگر نسبت به حل این مشکل کمک کنید.

کامپایلر استفاده شده: g++ (GCC) 9.2.0

g++ main.cpp mycurl.cpp -lcurl

کتابخانه مورد استفاده:  libcurl 7.67.0

سیستم عامل مورد استفاده:  گنو/لینوکس - توزیع آرچ لینوکس

 

کد مربوطه:

mycurl.h

#include <iostream>
#include <cstdlib>
#include <curl/curl.h>
#include <string>
using std::string;
using std::cout;
using std::cin;

class myCurl{
    public:
        myCurl(string u);
        ~myCurl();
        int response();
        string text();
    private:
        string url;
        CURLcode res;
        CURL *curl_handle;
        FILE *file;
        string filename;
        static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream);
        void perform();
};

 

mycurl.cpp

#include "mycurl.h"

myCurl::myCurl(string u){
    url = u;
    filename = "/tmp/curltemp.txt";
    curl_global_init(CURL_GLOBAL_ALL);
    curl_handle = curl_easy_init();
    curl_easy_setopt(curl_handle, CURLOPT_URL, u.c_str());
    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, file);
}

myCurl::~myCurl(){
    curl_easy_cleanup(curl_handle);
    curl_global_cleanup();
}

void myCurl::perform(){
    file = fopen(filename.c_str(), "wb");
    if(file) {
        res = curl_easy_perform(curl_handle);
    }
    fclose(file);
}

int myCurl::response(){
    perform();
    return static_cast<int>(res);
}

string myCurl::text(){
    return "";
}

size_t myCurl::write_data(void *ptr, size_t size, size_t nmemb, void *stream){
  size_t written = fwrite(ptr, size, nmemb, static_cast<FILE *>(stream));
  return written;
}

 

main.cpp

#include "mycurl.h"
int main(){

    myCurl a("ifconfig.co");
    cout << a.response() << std::endl;
    return 0;
}

 

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

1 پاسخ به این سوال تا کنون داده شده است

پست های پیشنهاد شده

  • 2
ارسال شده در (ویرایش شده)

سلام و درود بر شما؛

در این قسمت، قبل از اینکه متغیر FILE را ارسال کنید، با استفاده از تابع fopen فایل را باز کنید:

myCurl::myCurl(string u){
    url = u;
    filename = "/tmp/curltemp.txt";
    curl_global_init(CURL_GLOBAL_ALL);
    curl_handle = curl_easy_init();
    curl_easy_setopt(curl_handle, CURLOPT_URL, u.c_str());
    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, file);
}

به این‌صورت:

myCurl::myCurl(string u){
    url = u;
    filename = "/tmp/curltemp.txt";
    curl_global_init(CURL_GLOBAL_ALL);
    curl_handle = curl_easy_init();

    if(curl_handle)
    {
        file = fopen(filename.c_str(), "wb");
   
        curl_easy_setopt(curl_handle, CURLOPT_URL, u.c_str());
        curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, file);
    }
}

برای اینکه بخوای دقیقاً متوجه بشی که چرا خطا می‌داد، به خاطر این هست که کلاً در کتابخانه‌ی Curl هر تنظیماتی و هر رفتاری نسبت به هر شیء یا عمل بر روی اون رو باید همراه با پارامتر‌هاش که می‌تونه از نوع اشاره‌گری به شیء، تابع و یا نوعی از curl_off_t باشه، به کنترل کننده‌ی curl_easy_setopt تحویل داده بشه تا دقیقاً هر بلایی که سرش میاد رو کنترل کنه. در واقع یک سری سری جلسات حاوی رفتار‌ها رو برای کنترل می‌سازه و به هسته‌ی کتابخانه‌ی Curl ارائه می‌کنه تا بدونه چه رفتاری باید داشته باشه.

  • زمانی هم که نیاز باشه تنظیمات رفتاریِ اعمال شده توسط کاربر رو برای کتابخانه به صورت پیش‌فرض بازگردانی کنیم از curl_easy_reset استفاده خواهیم کرد.
  • مقدار دهی‌های اولیه هم کلاً بر عهده‌ی curl_easy_init هست.

در این مثال هم چون دقیقاً عملِ باز شدن و خوانده شدن فایل بر روی حافظه نامشخص بود و به طوری null دریافت می‌کرد، طبیعتاً خطای Segfaults باید رخ می‌داد.

برای اینکه بخوای جزئیات بیشتری رو هم به دست بیاریم می‌تونیم از مشخصه‌ی CURLOPT_VERBOSE استفاده کنیم تا جزئیات بیشتری از عملکرد کتابخانه رو در زمان اجراء رو ببینیم.

برای مثال :

curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

 

ویرایش شده در توسط قاسم رمضانی منش
اضافه‌کردن توضیحات آقای اسدزاده.

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

مهمان
پاسخ به این سوال ...

×   شما در حال چسباندن محتوایی با قالب بندی هستید.   حذف قالب بندی

  تنها استفاده از ۷۵ اموجی مجاز می باشد.

×   لینک شما به صورت اتوماتیک جای گذاری شد.   نمایش به عنوان یک لینک به جای

×   محتوای قبلی شما بازگردانی شد.   پاک کردن محتوای ویرایشگر

×   شما مستقیما نمی توانید تصویر خود را قرار دهید. یا آن را اینجا بارگذاری کنید یا از یک URL قرار دهید.


  • کاربران آنلاین در این صفحه   0 کاربر

    هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.

×
×
  • جدید...