Another update from ingydotnet^djgoku
This commit is contained in:
parent
91df62d461
commit
948b86eafa
7604 changed files with 108452 additions and 22726 deletions
|
|
@ -20,4 +20,5 @@ int main (int argc, char * argv [])
|
|||
putchar ('\n');
|
||||
}
|
||||
}</lang>
|
||||
Write an implementation of Query in your language and make ''main'' calling it. The function Query takes the buffer a places the string ''Here am I'' into it. The buffer size in bytes is specified by the parameter Length. When there is no room in the buffer, Query shall return 0. Otherwise it overwrites the beginning of Buffer, sets the number of overwritten bytes into Length and returns 1.
|
||||
|
||||
Implement the missing <code>Query</code> function in your language, and let this C program call it. The function should place the string ''<tt style="margin:0 0.5em">Here am I</tt>'' into the buffer which is passed to it as the parameter <code>Data</code>. The buffer size in bytes is passed as the parameter <code>Length</code>. When there is no room in the buffer, <code>Query</code> shall return 0. Otherwise it overwrites the beginning of <code>Buffer</code>, sets the number of overwritten bytes into <code>Length</code> and returns 1.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
!-----------------------------------------------------------------------
|
||||
!Function
|
||||
!-----------------------------------------------------------------------
|
||||
function fortran_query(data, length) result(answer) bind(c, name='Query')
|
||||
use, intrinsic :: iso_c_binding, only: c_char, c_int, c_size_t, c_null_char
|
||||
implicit none
|
||||
character(len=1,kind=c_char), dimension(length), intent(inout) :: data
|
||||
integer(c_size_t), intent(inout) :: length
|
||||
integer(c_int) :: answer
|
||||
answer = 0
|
||||
if(length<10) return
|
||||
data = transfer("Here I am"//c_null_char, data)
|
||||
length = 10_c_size_t
|
||||
answer = 1
|
||||
end function fortran_query
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// This buildmode requires the package to be main
|
||||
package main
|
||||
|
||||
// Import C so we can export the function to C and use C types
|
||||
|
||||
//#include <stdlib.h> // for size_t
|
||||
import "C"
|
||||
|
||||
// Import reflect and unsafe so we can wrap the C array in a Go slice
|
||||
import "reflect"
|
||||
import "unsafe"
|
||||
|
||||
// This buildmode also requires a main function, but it is never actually called
|
||||
func main() {}
|
||||
|
||||
// The message to copy into the buffer
|
||||
const msg = "Here am I"
|
||||
|
||||
// Here we declare the Query function using C types and export it to C
|
||||
|
||||
//export Query
|
||||
func Query(buffer *C.char, length *C.size_t) C.int {
|
||||
// Check there is enough space in the buffer
|
||||
if int(*length) < len(msg) {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Wrap the buffer in a slice to make it easier to copy into
|
||||
sliceHeader := reflect.SliceHeader {
|
||||
Data: uintptr(unsafe.Pointer(buffer)),
|
||||
Len: len(msg),
|
||||
Cap: len(msg),
|
||||
}
|
||||
bufferSlice := *(*[]byte)(unsafe.Pointer(&sliceHeader))
|
||||
|
||||
// Iterate through the message and copy it to the buffer, byte by byte
|
||||
for i:=0;i<len(msg);i++ {
|
||||
bufferSlice[i] = msg[i]
|
||||
}
|
||||
|
||||
// Set length to the amount of bytes we copied
|
||||
(*length) = C.size_t(len(msg))
|
||||
|
||||
return 1
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
typedef int strfun (char * Data, size_t * Length);
|
||||
strfun *Query = NULL;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#lang racket
|
||||
|
||||
(require ffi/unsafe)
|
||||
|
||||
(define xlib (ffi-lib "./x.so"))
|
||||
|
||||
(set-ffi-obj! "Query" xlib (_fun _pointer _pointer -> _bool)
|
||||
(λ(bs len)
|
||||
(define out #"Here I am")
|
||||
(let ([bs (make-sized-byte-string bs (ptr-ref len _int))])
|
||||
(and ((bytes-length out) . <= . (bytes-length bs))
|
||||
(begin (bytes-copy! bs 0 out)
|
||||
(ptr-set! len _int (bytes-length out))
|
||||
#t)))))
|
||||
|
||||
((get-ffi-obj "main" xlib (_fun _int (_list i _bytes) -> _void))
|
||||
0 '())
|
||||
Loading…
Add table
Add a link
Reference in a new issue