I am familiar with Ruby /DL but not sure how to us

2019-05-05 17:04发布

I have this function in this Module

require 'dl'
require 'dl/import'

module LibCalendars
  extend DL::Importer
  dlload './cal2jd.o'

  extern 'int iauCal2jd(int, int, int, double *, double *)'
end

How do I set this up in a Module to get access to the pointers?

Is what I need partly in there? I'm just not sure. How is this done correctly? The exact code is at http://www.iausofa.org/2013_1202_C/sofa/cal2jd.c I need to know how to access those address pointers. The validation tests are here http://www.iausofa.org/2013_1202_C/sofa/t_sofa_c.c

An almost equivalent main C would look something like this next code. I just made a copy of the cal2jd.c file and tacked the main function in at the bottom of it.

#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;
 }

I compile it with > gcc -o cal2jd cal2jd.c

Here's my output

$ 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

The status is good and djm0 is set by a constant in the header file sofam.h to 2400000.5 and you can see from the notes in the source file that it should always be that. You can see from the validation test file what djm should be.

I'm trying to do too much at once. I'm learning some C code while working with the SOFA code and trying to wrap that in Ruby. (JRuby actually) So I'll take answers for the C part, the DL or FFI or some good reference links.

I'm also considering ffi approach. Here is a start.

require 'ffi'

module MyLibrary
  extend FFI::Library
  ffi_lib "cal2jd.so"
  attach_function :iauCal2jd, [:int, :int, :int, :pointer, :pointer], :int
end

I'm really trying this in JRuby. Where do I go from here with pointers because I'm lost. Can I get some good examples please? Thanks in advance.

2条回答
Lonely孤独者°
2楼-- · 2019-05-05 17:40

Not sure to understand your question because of the ruby and jruby tags but if you are asking about C then: cfunction is a pointer to the function.

Let's say you have another function f taking a function pointer as parameter:

void f(void (*)(int , int , double *));

you can call f with:

f(cfunction);
查看更多
老娘就宠你
3楼-- · 2019-05-05 17:48

I've discovered a way to do what I had intended just recently. Here I will share it with you in case anyone wants to try this. First you have to compile your C library into a shared object file. Ask the C programmers how to do that. This is how I used the 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

My output is

0 # return result good
2400000.5
56753.0  # pretty soon we're gonna have a straight 56789 ;-)

Hope this might help somebody and thanks all for helping. Go ahead and leave more comments or better answers we can vote on.

查看更多
登录 后发表回答