在GHC FFI中包含C头文件时出现分析器错误

时间:2017-04-22 19:31:51

标签: haskell ghc ffi

我遵循示例(例如12)来构建数据结构,以便在GHC(8.0.2)中使用FFI传递给C程序。 C文件tagger-api.h是:

 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
     -}

cabal节是:

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文件是自动生成的,现在我有一个。我假设cabal会自动将.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的指针数组构造结构。

我很感激帮助澄清了我必须使用的预处理器并克服了第一道障碍。现在我在另一个人,非常感谢帮助。

1 个答案:

答案 0 :(得分:0)

这条新的错误消息表明目录nano中的nano /home/nipayl/.profile库实际上并不包含libtreetagger.a/home/frank/Workspace8/repo8/treeTaggerClient/treetaggerSourceC的定义,无论init_treetagger是什么说。

您可以运行tag_sentence,看看tagger-api.hnm libtreetagger.a是否真的在该文件中显示为已定义的符号?应该有这样的行:

init_treetagger

具体而言,名称应完全匹配,记录应包含地址,类型应为tag_sentence