-
Notifications
You must be signed in to change notification settings - Fork 4
Strings
Brandon Elam Barker edited this page May 21, 2020
·
1 revision
When looking into how to grab a string from the MATLAB Engine, it is possible to get a bit lost. There are a lot of functions after all. Here are a few I chased down that seemed possibly relevant:
engineEvalFun :: Engine -> String -> [EngineEvalArg a] -> Int -> IO [MAnyArray]
type MAnyArray = MXArray MAny
anyMXArray :: MXArray a -> MAnyArray
type MXArrayPtr = Ptr MXArrayType
foreign import ccall unsafe mxGetChars :: MXArrayPtr -> IO (Ptr MXChar)
-- `MXArrayType` appears to be an abstract type:
data MXArrayType
-- The only lead is this:
newtype MXAuto a = MXAuto (ForeignPtr MXArrayType)
mxAuto :: MXArray a -> MIO (MXAuto a)
-- However, MXAuto is: A 'MXArray' that is automatically freed. These arrays must never be put inside other arrays or used as function results.
type With x y a = x -> (y -> a) -> a
withMXArray :: With (MXArray x) MXArrayPtr a
-- == ??
withMXArray :: (MXArray x) -> (MXArrayPtr -> a) -> a
withMXArray (MXArray a) f = f a
-- So we give it an (MXArray MAny), and a function to extract
-- an `a` from a `MXArrayPtr`, and we should get an `a` as a result
-- I'm not entirely sure what the right way is to read this, but I
-- suppose "With x and y->a you get an a" isn't awful: it implies
-- the function embeds logic to go from x-> y.
mapWith :: With x y a -> With [x] [y] a
mapWith' :: With x y a -> With [x] [y] a
mapWithRev :: With x y a -> With [x] [y] a
mapWithArray :: Storable y => With x y (IO a) -> With [x] (Ptr y) (IO a)
mapWithArrayLen :: Storable y => With x y (IO a) -> With [x] (Ptr y, Int) (IO a)
withMXAuto :: MXAuto a -> (MXArray a -> IO b) -> IO b
type MAnyAuto = MXAuto MAny
-- |Get a flat list of all elements in the array.
mxArrayGetAll :: MXArrayComponent a => MXArray a -> IO [a]
In the end, the solution was to realize that:
-
instance MXArrayComponent MChar
exists (original error:No instance for (MXArrayComponent [Char])
) -
mxArrayGetAll
exsits
This allowed for writing an interface to MATLAB's pwd
(not necessarily the best interface in terms of error handling):
pwd :: Engine -> IO (Path Abs Dir)
pwd eng = do
[pwdDirAnyArr] <- engineEvalFun eng "pwd" [] 1
pwdDirCArrMay <- castMXArray pwdDirAnyArr
dirOrEmptyStr <- case pwdDirCArrMay of
Just pwdDirCArr -> mxArrayGetAll pwdDirCArr
Nothing -> pure ""
parseAbsDir dirOrEmptyStr