Use another language to call a function: Difference between revisions
Content added Content deleted
m (→Using carray: Nuke trailing spaces.) |
m (→Using cptr and memcpy: Nuke trailing spaces.) |
||
Line 1,128: | Line 1,128: | ||
An alternative approach is possible if we avail ourselves of the <code>memcpy</code> function via FFI. We can receive the data as an opaque foreign pointer represented by the <code>cptr</code> type. We can set up <code>memcpy</code> so that its destination argument and return value is a <code>cptr</code>, but the source argument is a string: |
An alternative approach is possible if we avail ourselves of the <code>memcpy</code> function via FFI. We can receive the data as an opaque foreign pointer represented by the <code>cptr</code> type. We can set up <code>memcpy</code> so that its destination argument and return value is a <code>cptr</code>, but the source argument is a string: |
||
<lang txrlisp>(with-dyn-lib "./query.so" |
<lang txrlisp>(with-dyn-lib "./query.so" |
||
(deffi query "query" void (closure))) |
(deffi query "query" void (closure))) |
||
(with-dyn-lib nil |
(with-dyn-lib nil |
||
(deffi memcpy "memcpy" cptr (cptr str size-t))) |
(deffi memcpy "memcpy" cptr (cptr str size-t))) |
||
(deffi-cb query-cb int (cptr (ptr (array 1 size-t)))) |
(deffi-cb query-cb int (cptr (ptr (array 1 size-t)))) |
||
(query (query-cb (lambda (buf sizeptr) ; int lambda(void *buf, |
(query (query-cb (lambda (buf sizeptr) ; int lambda(void *buf, siz |
||
(symacrolet ((size [sizeptr 0])) ; { #define size sizeptr[0] |
(symacrolet ((size [sizeptr 0])) ; { #define size sizeptr[0] |
||
(let* ((s "Here am I") ; char *s = "Here am I"; |
(let* ((s "Here am I") ; char *s = "Here am I"; |
||
(l (length s))) ; size_t l = strlen(s); |
(l (length s))) ; size_t l = strlen(s); |
||
(cond ; if (length > size) |
(cond ; if (length > size) |
||
((> l size) 0) ; { return 0; } else |
((> l size) 0) ; { return 0; } else |
||
(t (memcpy buf s l) ; { memcpy(buf, s, l); |
(t (memcpy buf s l) ; { memcpy(buf, s, l); |
||
(set size l)))))))) ; return size = l; } }</lang> |
(set size l)))))))) ; return size = l; } }</lang> |
||