2017-04-22 19 views
0

我使用以下示例(例如12)來構建數據結構,以使用GHC(8.0.2)中的FFI傳遞給C程序。 C文件tagger-api.h是:關於在GHC中包含C頭文件時的解析器錯誤FFI

typedef struct { 
    int number_of_words; /* number of words to be tagged */ 
    int next_word;  /* needed internally */ 
    char **word;   /* array of pointers to the words */ 
    char **inputtag;  /* array of pointers to the pretagging information */ 
    const char **resulttag;/* array of pointers to the tags */ 
    const char **lemma; /* array of pointers to the lemmas */ 
} TAGGER_STRUCT; 

void init_treetagger(char *param_file_name); 
double tag_sentence(TAGGER_STRUCT *ts); 

的代碼是在MainFFI4TT.hsc文件:

{-# LANGUAGE CPP #-} 
{-# LANGUAGE ForeignFunctionInterface #-} 
{-# LANGUAGE FlexibleInstances, RecordWildCards #-} 

module Main  where  -- must have Main (main) or Main where 

import Foreign 
import Foreign.C 

#include "tagger-api.h" 

main = do  
    withCString parameterFileName c_initTreeTagger  
    return() 

parameterFileName = "/home/frank/additionalSpace/AF_amd_install/treeTagger/TreeTaggerDaemon/lib/german-utf8.par" 

foreign import ccall "tagger-api.h init_treetagger" 
    c_initTreeTagger :: CString -> IO() 

foreign import ccall "tagger-api.h tag_sentence" 
    c_tag_sentence :: CString -> IO()  -- structure required.... 

data Struct = Struct -- this requires ccp 
    { noOfWords :: !Int 
    , nextWord :: !Int 
    , wordsIn :: ![String] 
    , pretag :: ![String] 
    , tags :: ![String] 
    , lemmas :: ![String] 
    } 
{- 
type StructPtr = Ptr Struct 
instance Storable Struct where 
    alignement _ = #{alignment TAGGER_STRUCT} 
    sizeOf _ = #{size TAGGER_STRUCT} 
    poke p Struct{..} = do 
     number_of_words <- newCString noOfWords 
     nextWord <- CInt nextWord 
    -} 

小集團節是:

executable ttclient 
    main-is: MainFFI4TT.hs 
    build-depends: base 
    default-language: Haskell2010 
    hs-source-dirs: src 
    other-modules: 
    Include-dirs: treetaggerSourceC 
    Includes: tagger-api.h 
    extra-libraries: treetagger 
    extra-lib-dirs: /home/frank/Workspace8/repo8/treeTaggerClient/treetaggerSourceC 

我感到困惑的文件是否應該有擴展.hsc.cpphs - 我是在錯誤的印象下,.hsc文件是自動生成的,現在我有一個。我假定小集團自動轉換.hsc.hs,但它現在失敗:

Linking dist/build/ttclient/ttclient ... 
dist/build/ttclient/ttclient-tmp/Main.o: In function `c3Lp_info': 
(.text+0x49a): undefined reference to `init_treetagger' 
dist/build/ttclient/ttclient-tmp/Main.o: In function `c3Nl_info': 
(.text+0x762): undefined reference to `tag_sentence' 
collect2: error: ld returned 1 exit status 
`gcc' failed in phase `Linker'. (Exit code: 1) 

接下來的問題將是如何與指針strigs的陣列構造的結構。

我很感謝幫助澄清了我必須使用的預處理器並克服了第一個障礙。現在我在另一個,非常感謝幫助。

+0

我投票結束,因爲您沒有提供足夠的信息。 haskell代碼在哪裏?你如何試圖建立這個? –

+1

看起來你正在使用'ghc',但已經使用CPP來包含一個C文件......當你在C代碼上使用Haskell編譯器時,你會怎麼想?你鏈接到討論'hsc2hs'的人,所以你可能想要安裝和使用它,而不是直接調用GHC。 –

回答

0

這個新的錯誤信息表明libtreetagger.a庫目錄/home/frank/Workspace8/repo8/treeTaggerClient/treetaggerSourceC實際上並不包含定義爲init_treetaggertag_sentence,無論tagger-api.h可能會說。

您可以運行nm libtreetagger.a並查看init_treetaggertag_sentence是否確實顯示爲該文件中的定義符號?應該有線條狀:

00000000000003b0 T init_treetagger 
0000000000001c40 T tag_sentence 

具體而言,它們的名稱應該嚴絲合縫,該記錄應包括地址和類型應該是T