For a C API, a slice would be a simple { void*, size_t } or { void*, void* } struct, but I guess for memory managed languages this isn't enough information to pin the underlying data into memory (for instance a reference to the underlying 'object' - don't know how such language-specific details could ever be expressed in a 'standard ABI').
Oh, it's simple enough, even with managed languages in the picture - it just needs to be decided once, and then everybody uses it.
The problem is that many existing ABIs don't optimize for small structs as function arguments particularly well, so just bolting it on like that can mean poor performance compared to old-school separate arguments for pointer and length. You want a hard guarantee that something like foo(slice1, slice2) will be passed entirely in the registers, not as two pointers-to-stack.