Я знаком с Ruby /DL, но не уверен, как использовать вызовы функций C, которые имеют указатели для возвращаемых параметров
У меня есть эта функция в этом модуле
require 'dl'
require 'dl/import'
module LibCalendars
extend DL::Importer
dlload './cal2jd.o'
extern 'int iauCal2jd(int, int, int, double *, double *)'
end
Как мне установить это в модуле, чтобы получить доступ к указателям?
Что мне там нужно? Я просто не уверен. Как это сделать правильно? Точный код на http://www.iausofa.org/2013_1202_C/sofa/cal2jd.c Мне нужно знать, как получить доступ к этим адресным указателям. Валидационные тесты здесь http://www.iausofa.org/2013_1202_C/sofa/t_sofa_c.c
Почти эквивалентный основной C будет выглядеть примерно так: Я просто сделал копию файла cal2jd.c и прикрепил основную функцию внизу.
#include <stdio.h>
int
main()
{
int y = 2003, m = 6, d = 1;
int j;
double djm0, djm;
double *pdjm0 = &djm0;
double *pdjm = &djm;
printf("values are: y == %d, m == %d, d == %d\n", y, m, d);
j = iauCal2jd(y, m, d, &djm0, &djm);
printf("j == %d\n", j);
printf("address of &djm0 == %p, size of pointer == %d\n", &djm0, sizeof(*pdjm0));
printf("address of &djm == %p, size of pointer == %d\n", &djm, sizeof(*pdjm0));
printf("value from &djm0 == %.20g, size of djm0 == %d\n", *pdjm0, sizeof(djm0));
printf("value from &djm == %.20g, size of djm == %d\n", *pdjm, sizeof(djm));
printf("value from &djm0 == %.3f\n", (float)*pdjm0);
printf("value from &djm == %.3f\n", (float)*pdjm);
return 0;
}
Я компилирую это с помощью> gcc -o cal2jd cal2jd.c
Вот мой вывод
$ cal2jd
values are: y == 2003, m == 6, d == 1
j == 0
address of &djm0 == 0022FF30, size of pointer == 8
address of &djm == 0022FF28, size of pointer == 8
value from &djm0 == 2400000.5, size of djm0 == 8
value from &djm == 52791, size of djm == 8
value from &djm0 == 2400000.500
value from &djm == 52791.000
Состояние хорошее, и djm0 задается константой в заголовочном файле sofam.h равным 2400000.5, и из заметок в исходном файле видно, что так должно быть всегда. Из файла теста проверки вы можете увидеть, каким должен быть djm.
Я пытаюсь сделать слишком много одновременно. Я изучаю некоторый код C, работая с кодом SOFA и пытаясь обернуть его в Ruby. (На самом деле JRuby) Так что я возьму ответы для части C, DL или FFI или некоторых хороших справочных ссылок.
Я также рассматриваю подход ffi. Вот начало.
require 'ffi'
module MyLibrary
extend FFI::Library
ffi_lib "cal2jd.so"
attach_function :iauCal2jd, [:int, :int, :int, :pointer, :pointer], :int
end
Я действительно пробую это в JRuby. Куда я пойду отсюда с указателями, потому что я потерян. Могу ли я получить несколько хороших примеров, пожалуйста? Заранее спасибо.
2 ответа
Не уверен, что понял ваш вопрос из-за тегов ruby и jruby, но если вы спрашиваете о C, то: cfunction
это указатель на функцию.
Допустим, у вас есть другая функция f, принимающая указатель на функцию в качестве параметра:
void f(void (*)(int , int , double *));
ты можешь позвонить f
с:
f(cfunction);
Я обнаружил способ сделать то, что я намеревался совсем недавно. Здесь я поделюсь этим с вами на случай, если кто-то захочет попробовать это. Сначала вы должны скомпилировать вашу библиотеку C в общий объектный файл. Спросите программистов на C, как это сделать. Вот как я использовал cal2jd.so.
require 'ffi'
module Calendars
extend FFI::Library
ffi_lib 'cal2jd.so'
attach_function :iauCal2jd, [:int, :int, :int, :pointer, :pointer ], :int
end
mp1 = FFI::MemoryPointer.new(:double, 8)
mp2 = FFI::MemoryPointer.new(:double, 8)
cal = Calendars.iauCal2jd(2014, 4, 6, mp1, mp2 )
puts cal
puts mp1.get_double, mp2.get_double
Мой вывод
0 # return result good
2400000.5
56753.0 # pretty soon we're gonna have a straight 56789 ;-)
Надеюсь, это кому-нибудь поможет и спасибо всем за помощь. Идите дальше и оставляйте больше комментариев или лучших ответов, по которым мы можем проголосовать.