2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -1,11 +1,16 @@
;Task:
Show how a [[Foreign function interface|foreign language function]] can be called from the language.
As an example, consider calling functions defined in the [[C]] language. Create a string containing "Hello World!" of the string type typical to the language. Pass the string content to [[C]]'s <code>strdup</code>. The content can be copied if necessary. Get the result from <code>strdup</code> and print it using language means. Do not forget to free the result of <code>strdup</code> (allocated in the heap).
Notes:
;Notes:
* It is not mandated if the [[C]] run-time library is to be loaded statically or dynamically. You are free to use either way.
* [[C++]] and [[C]] solutions can take some other language to communicate with.
* It is ''not'' mandatory to use <code>strdup</code>, especially if the foreign function interface being demonstrated makes that uninformative.
See also:
* [[Use another language to call a function]]
;See also:
* &nbsp; [[Use another language to call a function]]
<br><br>

View file

@ -0,0 +1,27 @@
identification division.
program-id. foreign.
data division.
working-storage section.
01 hello.
05 value z"Hello, world".
01 duplicate usage pointer.
01 buffer pic x(16) based.
01 storage pic x(16).
procedure division.
call "strdup" using hello returning duplicate
on exception
display "error calling strdup" upon syserr
end-call
if duplicate equal null then
display "strdup returned null" upon syserr
else
set address of buffer to duplicate
string buffer delimited by low-value into storage
display function trim(storage)
call "free" using by value duplicate
on exception
display "error calling free" upon syserr
end-if
goback.

View file

@ -0,0 +1,45 @@
module c_api
use iso_c_binding
implicit none
interface
function strdup(ptr) bind(C)
import c_ptr
type(c_ptr), value :: ptr
type(c_ptr) :: strdup
end function
end interface
interface
subroutine free(ptr) bind(C)
import c_ptr
type(c_ptr), value :: ptr
end subroutine
end interface
interface
function puts(ptr) bind(C)
import c_ptr, c_int
type(c_ptr), value :: ptr
integer(c_int) :: puts
end function
end interface
end module
program c_example
use c_api
implicit none
character(20), target :: str = "Hello, World!" // c_null_char
type(c_ptr) :: ptr
integer(c_int) :: res
ptr = strdup(c_loc(str))
res = puts(c_loc(str))
res = puts(ptr)
print *, transfer(c_loc(str), 0_c_intptr_t), &
transfer(ptr, 0_c_intptr_t)
call free(ptr)
end program

View file

@ -1,8 +1,8 @@
use NativeCall;
sub strdup(Str $s --> OpaquePointer) is native {*}
sub puts(OpaquePointer $p --> int) is native {*}
sub free(OpaquePointer $p --> int) is native {*}
sub puts(OpaquePointer $p --> int32) is native {*}
sub free(OpaquePointer $p --> int32) is native {*}
my $p = strdup("Success!");
say 'puts returns ', puts($p);

View file

@ -0,0 +1,13 @@
extern crate libc;
//c function that returns the sum of two integers
extern {
fn add_input(in1: libc::c_int, in2: libc::c_int) -> libc::c_int;
}
fn main() {
let (in1, in2) = (5, 4);
let output = unsafe {
add_input(in1, in2) };
assert!( (output == (in1 + in2) ),"Error in sum calculation") ;
}