2012-02-07 2 views
2

나는 벡터리스트를 가지고 있습니다. 타입 집합은 알려져 있고 고정되어 있습니다. 우리는 CIntCChar을 말합니다. 목록은 컴파일 타임에 알 수 없습니다. 구성은 런타임에 구성 파일에서 결정됩니다. 예를 들어, C 함수에 두 개의 벡터를 전달해야한다고 결정할 수 있습니다. 길이가 10 인 CInt 벡터 중 하나는 CChar 길이가 50 인 벡터입니다. C 함수가이를 해석하는 방법에 대해서는 다음과 같은 벡터 인코딩 유형을 전달하여 해당 논리를 처리 할 수 ​​있습니다. 각 벡터 (예 : 0 =>CInt, 1 =>CChar) 및 전달 된 각 벡터의 벡터 인코딩 길이 (10,50).C 함수에 저장된 저장 가능 벡터 전달하기

내가 알아 내려고하는 것은 혼합 된 벡터의 벡터를 생성하는 방법입니다 (C로 전달하기위한 것임). 나는 아래에있는 것과 같은 장난감 솔루션을 시도했다. (동일한 아이디어를 모델링한다. 실제 코드에서 각각의 Ptr은 다른 Storable 벡터를 가리킬 것이다.) - 복잡한 유형의 Ptr의 저장 가능한 벡터를 생성한다. 유형 오류로 인해 실패했습니다. 이전에 다른 question에서 지적했듯이 실제로 존재하는 정규화 된 유형과 관련이 있다고 생각합니다. C FFI로 전달하기 위해 Storable 인스턴스를 사용하고 있기 때문에 다른 저장 가능한 인스턴스를 정의하지 않고 유형을 래핑 할 수 없다고 생각합니다. ghci 7.4.1에서

{-# LANGUAGE BangPatterns, GADTs #-} 
import Data.Vector.Storable as SV 
import Foreign.C.Types (CChar, CInt) 
import GHC.Int (Int32) 
import Foreign.Marshal.Alloc 
import Foreign.Ptr (Ptr) 

mallocInt :: IO (Ptr CInt) 
mallocInt = malloc 

mallocChar :: IO (Ptr CChar) 
mallocChar = malloc 

main = do 
    a <- mallocInt 
    b <- mallocChar 
    let c = SV.fromList [a,b] 
    return() 

오류 :

test.hs:17:26: 
    Couldn't match expected type `CInt' with actual type `CChar' 
    Expected type: Ptr CInt 
     Actual type: Ptr CChar 
    In the expression: b 
    In the first argument of `fromList', namely `[a, b]' 
Failed, modules loaded: none. 

내가 위의 문제를 해결하는 방법에 대한 포인터를 주셔서 감사합니다. Data.Vector.Storable.Mutable.new 및 unsafeWrite를 사용하여 사용자 정의 벡터 채우기 함수를 작성할 수 있지만 여전히 혼합 유형을 적합해야합니다.

답변

5

C와 마찬가지로 char *int *void *으로 캐스팅해야 일반 배열로 저장할 수 있습니다. 따라서 벡터에 삽입하기 전에 Ptr CChar 및 을 Ptr()으로 전송하십시오.

당신은 너무처럼 Foreign.Ptr.castPtr 함수를 사용하여 포인터를 캐스팅 할 수 있습니다

intPtr :: Ptr CInt 
intPtr = undefined -- dummy value 

voidPtr :: Ptr() 
voidPtr = castPtr intPtr 
+0

당신이 방법도'의 PTR에'의 PTR CChar' 캐스팅의 예를 제시해주십시오 수()'하스켈? Unsafecoerce를 사용 하시겠습니까? – Sal

+0

@sal, 확실한 것! 몇 가지 예제 코드를 추가했습니다. – dflemstr

+0

매우 감사드립니다. – Sal

관련 문제