C ile iletişim kuran bir Haskell programı yazmaya çalışıyorum (en sonunda iOS ile GHC-iOS üzerinden). C'den Haskell'e bir dizgeyi iletmesini istiyorum, Haskell'i işlemek ve sonra Haskell'den C Structs'a bazı Data tiplerini hsc2s ile döndürmek istiyorum. Net, basit bir öğretici bulmakta başarısız oldum. Haskell'in C'den ihtiyacı olan tek şey, String, başka bir şey değil.hsc2hs: Haskell ile bir C yapısını değiştir
İlk kısımda bir sorunum yok, Haskell'e bir ip geçiriyorum.
testPrint :: CString -> IO()
testPrint c = do
s <- peekCString c
putStrLn s
Test amacıyla ve ileride başvurmak için, sadece aşağıdaki gibi bir şeyle başa çıkmak istiyorum.
C Planı
struct testdata {
char *a;
char *b;
int c;
};
Haskell Veri Türü
data TestData = TestData {
a :: String,
b :: String,
c :: Int
} deriving Show
-- not sure what the type would look like
testParse :: CString -> TestData
Ben göz depolanabilir olarak TestData typeclass ve uygulamak gerektiğini anlamanızı dürter, sizeof ve hizalama, ama basit görmeliyim önce gerçekten anlayabiliyorum. Öğreticilerin çoğu, dış kütüphaneleri gerektirir ve olması gerekenden daha karmaşık hale getirir.
Stackoverflow - How to use hsc2hs to bind to constants, functions and data structures?
Haskell Cafe - FFI for a beginner
Writing Haskell interfaces to C code: hsc2hs
Düzenleme:
İşte baktım kaynaklardır Şu anda takılıp nerede (segmentasyon hatası olduğunda alır setFoo C olarak adlandırılır
Haskell Kod Parçacığı
instance Storable Foo where
sizeOf = #{size foo}
alignment = alignment (undefined :: CString)
poke p foo = do
#{poke foo, a} p $ a foo
#{poke foo, b} p $ b foo
#{poke foo, c} p $ c foo
peek p = return Foo
`ap` (#{peek foo, a} p)
`ap` (#{peek foo, b} p)
`ap` (#{peek foo, c} p)
foreign export ccall "setFoo" setFoo :: Ptr Foo -> IO()
setFoo :: Ptr Foo -> IO()
setFoo f = do
newA <- newCString "abc"
newB <- newCString "def"
poke f (Foo newA newB 123)
Cı Kod Parçacığı
foo *f;
f = malloc(sizeof(foo));
foo->a = "bbb"
foo->b = "aaa"
foo->c = 1
// this is incorrect
// setFoo(&f);
// this is correct
setFoo(f);
çalıştırın. Şu anda çalışmakta olduğum problem, 'TestData' 'yı C'ye döndüren bir fonksiyonun nasıl dışa aktarılacağıdır. Bence bu' testParse :: CString -> IO (Ptr TestData) 'gibi görünmesi gerekiyor ama nasıl emin olacağımı bilmiyorum. TestData bir Ptr içine sarın. TestData için bir Storable örneğim var. – MCH
'testParse :: CString -> IO (StablePtr TestData)' ile derlemek için var ama C içinde segmentasyon hatası alıyorum. Belki de Storable kurulum yoludur. Kodu daha sonra gönderirim. – MCH
varolan Haskell FFI C bağlarının kaynak kodunu incelemeyi denediniz mi? Bunun gibi bir şey ilk kez denemediğinden eminim. –