やりたいこと
Nim言語でMeCabを呼び出し、形態素解析を行いたい。
環境
- Windows10 Home 64bit
- nim 0.19.6
※nimはscoopを使ってインストールしました。
詳細
Nim で mecab を使ってみた(C++バージョン)という記事を見かけ、
NimでもMeCabが使えるということで早速Windowsマシンで実行を試みました。
上記記事はMac用だったので、コードを以下のように少し変更しました。
parser.nim
nim
1{.link: "./MeCab/bin/libmecab.dll".} 2{.link: "./MeCab/bin/libmecab.lib".} 3 4{.emit: """ 5using namespace MeCab; 6""".} 7 8const header = "<MeCab.h>" 9 10type MeCabModelObj {.final, header: header, importcpp: "MeCab::Model".} = object 11type MeCabModel = ptr MeCabModelObj 12type MeCabTaggerObj {.final, header: header, importcpp: "MeCab::Tagger".} = object 13type MeCabTagger = ptr MeCabTaggerObj 14type MeCabLatticeObj {.final, header: header, importcpp: "MeCab::Lattice".} = object 15type MeCabLattice = ptr MeCabLatticeObj 16type ccstring {.importc:"const char*".} = object 17 18proc createModel(argv: cstring): MeCabModel {.header: header, importcpp: "createModel(@)".} 19proc createTagger(this: MeCabModel): MeCabTagger {.header: header, importcpp: "#.createTagger()".} 20proc createLattice(this: MeCabModel): MeCabLattice {.header: header, importcpp: "#.createLattice()".} 21proc setSentence(this: MeCabLattice, sentence: cstring): void {.header: header, importcpp: "#.set_sentence(@)".} 22proc parse(this: MeCabTagger, lattice: MeCabLattice): bool {.header: header, importcpp: "#.parse(@)".} 23proc toString(this: MeCabLattice): ccstring {.header: header, importcpp: "#.toString()".} 24 25type ParserObj = object 26 tagger: MeCabTagger 27 lattice: MeCabLattice 28 29type Parser* = ref ParserObj 30 31proc createParser*(): Parser = 32 const option: cstring = "" 33 34 let model = createModel(option) 35 let tagger = createTagger(model) 36 let lattice = createLattice(model) 37 38 return Parser(tagger: tagger, lattice: lattice) 39 40proc parse*(parser: Parser, sentence: string): string = 41 parser.lattice.setSentence(sentence) 42 let ret = parser.tagger.parse(parser.lattice) 43 if not ret: 44 raise newException(ValueError, "failed to parse.") 45 46 let str = cast[cstring](parser.lattice.toString()) 47 return $str
test.nim
nim
1import os 2import parser 3 4proc main() = 5 let arguments = commandLineParams() 6 if arguments.len() < 1: 7 echo "何か文を入力してください。" 8 return 9 10 let sentence = arguments[0] 11 12 let parser = createParser() 13 let str = parser.parse(sentence) 14 15 echo str 16 17when isMainModule: 18 main()
そしてプロジェクトフォルダにMeCabのインストールデータをフォルダごと移動します。
sdkフォルダの中身、「mecab.h」をnimのlibフォルダ(\nim\0.19.6\lib)に入れます
この状態で、
bash
1nim cpp -r test.nim
を叩くと、以下のエラーが出ます。
C:\Users\username\nimcache\test_d\parser.cpp.o:parser.cpp:(.text+0x126): undefined reference to `__imp__ZN5MeCab11createModelEPKc' collect2.exe: error: ld returned 1 exit status Error: execution of an external program failed: 'g++.exe -o C:\project\nim\mecab\test.exe C:\project\nim\mecab./MeCab/bin/libmecab.lib C:\project\nim\mecab./MeCab/bin/libmecab.dll C:\Users\username\nimcache\test_d\test.cpp.o C:\Users\username\nimcache\test_d\stdlib_system.cpp.o C:\Users\username\nimcache\test_d\stdlib_os.cpp.o C:\Users\username\nimcache\test_d\stdlib_strutils.cpp.o C:\Users\username\nimcache\test_d\stdlib_parseutils.cpp.o C:\Users\username\nimcache\test_d\stdlib_math.cpp.o C:\Users\username\nimcache\test_d\stdlib_bitops.cpp.o C:\Users\username\nimcache\test_d\stdlib_algorithm.cpp.o C:\Users\username\nimcache\test_d\stdlib_unicode.cpp.o C:\Users\username\nimcache\test_d\stdlib_times.cpp.o C:\Users\username\nimcache\test_d\stdlib_options.cpp.o C:\Users\username\nimcache\test_d\stdlib_typetraits.cpp.o C:\Users\username\nimcache\test_d\stdlib_strformat.cpp.o C:\Users\username\nimcache\test_d\stdlib_macros.cpp.o C:\Users\username\nimcache\test_d\stdlib_winlean.cpp.o C:\Users\username\nimcache\test_d\stdlib_dynlib.cpp.o C:\Users\username\nimcache\test_d\stdlib_ospaths.cpp.o C:\Users\username\nimcache\test_d\parser.cpp.o
当方、C++を書いたことがないのでエラーがあまり良く認識できません。
また、冒頭に書いたQiitaのコードをMacで動かすと、正常に動作しております。
この原因と解決方法を御存知の方がいらっしゃいましたら、ご教示いただけますと幸いです。
よろしくお願いいたします。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/08/31 01:54