2016-01-28 59 views
0

我正在嘗試使用Haskell和Repa/DevIL對圖形文件執行一系列轉換。使用的開始示例由Haskell wiki頁面https://wiki.haskell.org/Numeric_Haskell:_A_Repa_Tutorial提供。我是一名有30年經驗的程序員,他在一些教室環境下嘗試學習Haskell,這是一種很好的測量方法。haskell FFI將C結構數組傳入和傳出

問題是操作數據之後的文件負載首先轉化爲惹巴數組:

import Data.Array.Repa.IO.DevIL (runIL,readImage,writeImage,Image(RGB),IL) 
import qualified Data.Array.Repa as R 
import Data.Vector.Unboxed as DVU 
import Control.Monad 

main :: IO() 
main = do 
    [f] <- getArgs 
    (RGB a) <- runIL $ Data.Array.Repa.IO.DevIL.readImage f 
    let 
    c = (computeP (R.traverse a id rgbTransform)) :: IL (Array U DIM3 Float) 

其被成功地轉換爲類型「排列F DIM3浮動」從rgbTransform輸出。從這一點來看,使用這些數據一直是一場噩夢。輕拂F(的外國人)和U(nboxed)之間的陣列存儲類型改變了所有下面的調用的可用性,再加上第一繼添加惹巴單子層IL力使用liftM的幾乎每一個方程變換:

let -- continued 
    sh = liftM R.extent c -- IL DIM3 
    v = liftM R.toUnboxed c -- IL (Vector Float) 
    lv = liftM DVU.length v -- IL Int 
    f = liftM indexed v -- vector of tuples: (Int,a) where Int is idx 
    k = (Z :. 2) :. 2 :. 0 :: DIM3 

這些是我可以打電話沒有錯誤的例程。由於IL monad層,IO monad的print命令如果放置在「let」列表中或之後,則不會生成輸出。

爲好奇的比賽計劃:

  1. 讀取圖形文件(做,通過惹巴)
  2. 調整大小的圖像(不這樣做,在惹巴沒有調整大小,必須是手工編碼)
  3. 從Word8變換和轉換圖像爲Float(完成)
  4. 得到Stablepointer到經變換的浮動數據(未完成)
  5. 就地變換浮動的數據作爲C結構的陣列的 {浮法A,b, C;} ,通過FFI的外部C程序(不完全是 完成)。這是希望沒有編組一個新的圖形 數組通過傳遞數據的指針
  6. 執行更多通過轉換後的數據以提取更多的信息(部分完成)。

我尋求幫助與問題4和5

4 - >系統的類型已經很難對付在試圖獲得C-可用內存指針。通過haskell圖書館電話山脈沒有幫助。

5 - >外部C例程的類型爲:

foreign import ccall unsafe "transform.h xform" 
c_xform :: Ptr (CFloat,CFloat,CFloat) -> 
      CInt -> 
      IO() 

在PTR預計指向未裝箱平數組c rgb_t結構的:

typedef struct 
{ 
    float r; 
    float g; 
    float b; 
} rgb_t; 

推介基於web的FFI如果不是徹頭徹尾的晦澀難懂,那麼如何處理FFI中的數組指針的描述是不存在的。我想到的是,解凍和傳遞C數組浮點RGB結構的相當簡單的想法,在原地進行修改然後凍結結果。外部轉換是純粹的,因爲相同的輸入將產生可預測的輸出,不使用線程,不使用全局變量,也不依賴於不明確的庫。

+2

ERR ...類型的值'PTR(CFloat,CFloat,CFloat)'是通過無保證指向裝置一個內存位置,可以有意義地被視爲一個C結構,其中有三個'float's。我希望你不會依賴於你的遊戲計劃......(AFAIK在FFI規範中沒有*規定處理交易與C結構。) –

回答

4

Foreign.Marshal。Array似乎提供了一種將haskell數據轉換爲C數據和其他方式的方法。

我測試接口的C代碼,並使用以下的文件(Haskell的+ FFI首次對我來說)

hsc2hs rgb_ffi.hsc 
ghc main.hs rgb_ffi.hs rgb.c 

rgb.h

#ifndef RGB_H 
#define RGB_H 

#include <stdlib.h> 

typedef struct { 
    float r; 
    float g; 
    float b; 
} rgb_t; 

void rgb_test(rgb_t * rgbs, ssize_t n); 

#endif 

rgb.h Haskell的

#include <stdlib.h> 
#include <stdio.h> 
#include "rgb.h" 

void rgb_test(rgb_t * rgbs, ssize_t n) 
{ 
    int i; 

    for(i=0; i<n; i++) { 
     printf("%.3f %.3f %.3f\n", rgbs[i].r, rgbs[i].g, rgbs[i].b); 
     rgbs[i].r *= 2.0; 
     rgbs[i].g *= 2.0; 
     rgbs[i].b *= 2.0; 
    } 
} 

rgb_ffi.hsc

{-# LANGUAGE ForeignFunctionInterface #-} 
{-# LANGUAGE CPP      #-} 

module RGB where 

import Foreign 
import Foreign.C 
import Control.Monad (ap) 

#include "rgb.h" 

data RGB = RGB { 
     r :: CFloat, g :: CFloat, b :: CFloat 
} deriving Show 

instance Storable RGB where 
    sizeOf _ = #{size rgb_t} 
    alignment _ = alignment (undefined :: CInt) 

    poke p rgb_t = do 
     #{poke rgb_t, r} p $ r rgb_t 
     #{poke rgb_t, g} p $ g rgb_t 
     #{poke rgb_t, b} p $ b rgb_t 

    peek p = return RGB 
      `ap` (#{peek rgb_t, r} p) 
      `ap` (#{peek rgb_t, g} p) 
      `ap` (#{peek rgb_t, b} p) 

foreign import ccall "rgb.h rgb_test" crgbTest :: Ptr RGB -> CSize -> IO(); 

rgbTest :: [RGB] -> IO [RGB] 
rgbTest rgbs = withArray rgbs $ \ptr -> 
       do 
       crgbTest ptr (fromIntegral (length rgbs)) 
       peekArray (length rgbs) ptr 

rgbAlloc :: [RGB] -> IO (Ptr RGB) 
rgbAlloc rgbs = newArray rgbs 

rgbPeek :: Ptr RGB -> Int -> IO [RGB] 
rgbPeek rgbs l = peekArray l rgbs 

rgbTest2 :: Ptr RGB -> Int -> IO() 
rgbTest2 ptr l = 
    do 
     crgbTest ptr (fromIntegral l) 
     return() 

main.hs

module Main (main) where 

import RGB 

main = 
do 
    let a = [RGB {r = 1.0, g = 1.0, b = 1.0}, 
      RGB {r = 2.0, g = 2.0, b = 2.0}, 
      RGB {r = 3.0, g = 3.0, b = 3.0}] 
    let l = length a 
    print a 
    -- b <- rgbTest a 
    -- print b 

    c <- rgbAlloc a 
    rgbTest2 c l 
    rgbTest2 c l 
    d <- rgbPeek c l 
    print d 
    return() 
+0

感謝您的積極建議和代碼JJHakala。我會非常仔細地研究這個問題,看看如何使它符合所述問題之一。乾杯,查斯。 –