【问题标题】:Parser error on including a C header file in GHC FFI在 GHC FFI 中包含 C 头文件的解析器错误
【发布时间】:2017-09-19 16:43:10
【问题描述】:

我正在按照示例(例如 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
     -}

阴谋节是:

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)

下一个问题将是如何用指向字符串的指针数组构造结构。

我很感激在澄清我必须使用什么预处理器和克服第一个障碍方面的帮助。现在我在另一个地方,非常感谢您的帮助。

【问题讨论】:

  • 我投票结束,因为您没有提供足够的信息。哈斯克尔代码在哪里?您打算如何构建它?
  • 看来您使用的是ghc,但使用了CPP 来包含C 文件...您认为在C 代码上使用Haskell 编译器时会发生什么?您链接到谈论 hsc2hs 的人,所以也许您想安装和使用它而不是直接调用 GHC。

标签: haskell ghc ffi


【解决方案1】:

这条新的错误消息表明,/home/frank/Workspace8/repo8/treeTaggerClient/treetaggerSourceC 目录中的libtreetagger.a 库实际上并不包含init_treetaggertag_sentence 的定义,无论tagger-api.h 可能会说什么。

您能否运行nm libtreetagger.a 并查看init_treetaggertag_sentence 是否实际上在该文件中显示为已定义的符号?应该有这样的行:

00000000000003b0 T init_treetagger
0000000000001c40 T tag_sentence

具体来说,名称应完全匹配,记录应包括地址,类型应为T

【讨论】:

    猜你喜欢
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    相关资源
    最近更新 更多