Использование curl / libcurl в расширении C Ruby - PullRequest
1 голос
/ 07 июня 2011

Предисловие: я очень плохо знаком с C, поэтому, возможно, мне не хватает чего-то очевидного, но я несколько дней бегал, пытаясь понять, что это ...

Я пытаюсь создать RubyРасширение C, которое будет работать как на Mac, так и на ПК и которое использует libcurl для загрузки файлов.

По сути, все, что делает инструмент - получает список файлов из Ruby, загружает файлы и помещает их туда, куда Ruby говорит им,

У меня есть расширение, работающее из Ruby, и я скомпилировал расширение C для взаимодействия с Ruby.

В основном мой код выглядит так:

#include <string.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include "ruby.h"

VALUE Test = Qnil;

void Init_test();

VALUE download_file(VALUE self, VALUE from, VALUE to);

void Init_test()
{
    Test = rb_define_class("Test", rb_cObject);
    rb_define_method(Test, "download_file", download_file, 2);
}

VALUE download_file(VALUE self, VALUE from, VALUE to)
{
    CURL *curl;
    FILE *fp;
    CURLcode res;

    char *url = STR2CSTR(from);
    char outfilename[FILENAME_MAX] = STR2CSTR(to);

    curl = curl_easy_init();
    if (curl) {
        fp = fopen(outfilename,"wb");
        curl_easy_setopt(curl, CURLOPT_URL, url);
        // curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        fclose(fp);
    }
    return 0;
}

Что явозникают проблемы с получением libcurl:

$ ruby test.rb
dyld: lazy symbol binding failed: Symbol not found: _curl_easy_init
  Referenced from: /path/to/test.bundle
  Expected in: flat namespace

dyld: Symbol not found: _curl_easy_init
  Referenced from: /path/to/test.bundle
  Expected in: flat namespace

Trace/BPT trap

Я использую Ruby's mkmf, чтобы создать Makefile для моего расширения:

require 'mkmf'
extension_name = 'test'
dir_config(extension_name)
create_makefile(extension_name)

Я предполагаю, что при компиляциирасширения, Makefile не может найти эти файлы Curl, но так как я новичок в расширениях C / Ruby, я не могу понять, почему это так.

Когда я запускаю curl-config --cflags, это то, что я получаю:

$  curl-config --cflags
-I/usr/local/include

Мои файлы libcurl включают / библиотеки:

/usr/local/include/curl/
/usr/local/lib/libcurl.dylib

Мои настройки:

  • Mac OSX 10.6.4
  • Ruby 1.8.6-p420
  • Curl 7.21.7-DEV (i386-apple-darwin10.7.0) libcurl / 7.21.7-DEV OpenSSL / 0.9.8l zlib / 1.2.3

Любая помощьбудет принята с благодарностью!

Приветствия

Ответы [ 2 ]

1 голос
/ 07 июня 2011

Вы должны указать mkmf ссылку на libcurl при сборке вашего расширения. Используемая команда: have_library.

В вашем exconf.rb добавьте

have_library("curl", "curl_easy_init")

до звонка на create_makefile.

Кроме того, я не думаю, что вам нужна строка dir_config(extension_name).

(На Mac вы можете увидеть, какие библиотеки связаны с двоичным файлом с помощью otool -L. Попробуйте

otool -L test.bundle

до и после добавления have_library, вы должны увидеть строку типа /usr/lib/libcurl.4.dylib (compatibility version 6.0.0, current version 6.1.0) добавлено.)

1 голос
/ 07 июня 2011

Symbol not found: _curl_easy_init звучит как ошибка ссылки для меня.Похоже, вы должны передать какие-то флаги вашему компоновщику (см. curl-config --libs)

...