Logo

Programming-Idioms

This language bar is your friend. Select your favorite languages!

Idiom #190 Call an external C function

Declare an external C function with the prototype

void foo(double *a, int n);

and call it, passing an array (or a list) of size 10 to a and 10 to n.

Use only standard features of your language.

use FFI::Platypus qw();
FFI::Platypus
    ->new(lib => '/tmp/mylib/libmylib.so')
    ->attach(foo => ['double[]', 'int']);
foo([1..10], 10);
with Interfaces.C;
procedure C_Foo (A : access Interfaces.C.double;
                 N : Interfaces.C.int) with
   Import        => True,
   Convention    => C,
   External_Name => "foo";

procedure Test_Foo is
   type Double_Array is array (Positive range <>) of aliased Interfaces.C.double;
   A : Double_Array (1 .. 10) := (1.0, 2.0, 3.0, 4.0, 5.0,
                                  6.0, 7.0, 8.0, 9.0, 10.0);
begin
   C_Foo (A (A'First)'Access, A'Length);
end Test_Foo;
void foo(double *a, int n);
double a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
foo (a, sizeof(a)/sizeof(*a));
extern "C" void foo(double *a, int n);
module x
  use iso_c_binding
  interface
     subroutine foo (a, n) bind(c)
       import
       real(kind=c_double), dimension(*) :: a
       integer (kind=c_int), value :: n
     end subroutine foo
  end interface
contains
  subroutine call_foo
    real(kind=c_double) :: a(10)
    call foo(a,10)
  end subroutine call_foo
end module x
// void foo(double *a, int n);
// double a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
import "C"

C.foo(C.a, 10)
procedure foo(a: pdouble; n: integer); external 'some_c_dll' name 'foo'; cdecl;
from ctypes import *
a = (c_int * 10)(*range(10))
n = 10
libc = cdll.LoadLibrary('/path/to/c_library')
libc.foo(c_void_p(a), c_int(n))
extern "C" {
    /// # Safety
    ///
    /// `a` must point to an array of at least size 10
    fn foo(a: *mut libc::c_double, n: libc::c_int);
}

let mut a = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0];
let n = 10;
unsafe {
    foo(a.as_mut_ptr(), n);
}

New implementation...
< >
tkoenig