我遵循示例(例如1或2)来构建数据结构,以便在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的指针数组构造结构。
我很感激帮助澄清了我必须使用的预处理器并克服了第一道障碍。现在我在另一个人,非常感谢帮助。
答案 0 :(得分:0)
这条新的错误消息表明目录nano
中的nano /home/nipayl/.profile
库实际上并不包含libtreetagger.a
或/home/frank/Workspace8/repo8/treeTaggerClient/treetaggerSourceC
的定义,无论init_treetagger
是什么说。
您可以运行tag_sentence
,看看tagger-api.h
和nm libtreetagger.a
是否真的在该文件中显示为已定义的符号?应该有这样的行:
init_treetagger
具体而言,名称应完全匹配,记录应包含地址,类型应为tag_sentence
。