2017-04-22 43 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