diff --git a/collects/ffi/unsafe/com.rkt b/collects/ffi/unsafe/com.rkt index 5deec7e37a..6fd41d13cd 100644 --- a/collects/ffi/unsafe/com.rkt +++ b/collects/ffi/unsafe/com.rkt @@ -1385,6 +1385,8 @@ (= (vector-length arg) (cadr type)) (for/and ([v (in-vector arg)]) (ok-argument? v (caddr type))))] + [(eq? 'variant (car type)) + (ok-argument? arg (cadr type))] [else #f])) (define (type-description? type) @@ -1426,6 +1428,9 @@ (and (= (length type) 3) (exact-positive-integer? (cadr type)) (type-description? (caddr type)))] + [(eq? 'variant (car type)) + (and (= (length type) 2) + (type-description? (cadr type)))] [else #f])] [else #f])) @@ -1456,6 +1461,8 @@ (cond [(type-described? a) (scheme-to-variant! var (type-described-value a) elem-desc scheme-type)] + [(and (pair? scheme-type) (eq? 'variant (car scheme-type))) + (scheme-to-variant! var a elem-desc (cadr scheme-type))] [(eq? a com-omit) (if (and elem-desc (elem-desc-has-default? elem-desc)) @@ -1596,6 +1603,8 @@ [else (values null t)]))) (_safe-array/vectors dims base)] + [(eq? 'variant (car type)) + (to-ctype (cadr type))] [else #f])) (define (to-vt type) @@ -1624,6 +1633,7 @@ (car type)) [(array) (bitwise-ior VT_ARRAY (to-vt (caddr type)))] [(opt) (to-vt (cadr type))] + [(variant) VT_VARIANT] [else (error 'to-vt "Internal error: unsupported type ~s" type)])])) diff --git a/collects/scribblings/foreign/com-auto.scrbl b/collects/scribblings/foreign/com-auto.scrbl index eb1d48cf23..66a72f95b0 100644 --- a/collects/scribblings/foreign/com-auto.scrbl +++ b/collects/scribblings/foreign/com-auto.scrbl @@ -456,6 +456,14 @@ integer, such as @racket['(array 7 int)], represents a vector of values to be used as a COM array. Array types can be nested to specify a multidimensional array as represented by nested vectors. +A type wrapped in a list with @racket['variant], such as +@racket['(variant (array 7 int))], is the same as the wrapped type, +but a @racket['variant] wrapper within an @racket['array] type prevents +construction of another array dimension. For example, @racket['(array 2 (array 3 +int))] is a two-dimensional array of integers, but @racket['(array 2 +(variant (array 3 int)))] is a one-dimensional array whose elements +are one-dimensional arrays of integers. + When type information is not available, functions like @racket[com-invoke] infer type descriptions from arguments. Inference chooses @racket['boolean] for booleans; the first of @racket['int], @racket['unsigned-int],