Raspberry Piに喋らせてみるみたいなことで使ってる人もいるのかもしれない OpenJTalk. これをC# でラップして,ライブラリ化して使いたいなと思ったためちょこちょこと作業をしていました.
実際のC/C++のプロジェクトがこちら
GitHub - yamachu/LibOpenJTalk: Unofficial OpenJTalk mirror
そして成果物のC# ラッパーがこちら
以前このブログでも紹介したように各プラットフォームでネイティブのライブラリをビルドし,DllImport属性などを使ってラップしていくやり方で行っていたのですが,どうもWindows環境で日本語をネイティブ側に渡そうとすると文字コードの問題が発生してしまうと言った問題が起こりました.
結論としてはAppVeyorの言語ロケールが英語になっていたため,ソースコードをUTF-8で保存されたものと解釈しそのままビルドが行われたりしたことが問題でした. またコマンドラインオプションを使用しないとビルドすら通らなかったため,AppVeyorでビルドする際はそのあたりも考えたほうが良かったみたいです.
まずはビルドを通るようにするには,cl.exe のオプションに対象ソースコードの文字コードを記述します.
自分はSJISで保存されたファイルだったので /source-charset:.932
を追記しました.
こちらの記事が非常に参考になりました.
Visual C++(cl.exe)で UTF-8 のファイルをコンパイルする - Bite Code
この修正によりビルドが通るようになりましたが,複数のwarningが発生し,また生成されたライブラリで日本語の扱いがうまくいかないバグが発生しました. 実際の warning は以下のとおりです.
c:\projects\libopenjtalk\text2mecab\text2mecab_rule_shift_jis.h(75): warning C4566: character represented by universal-character-name '\u3000' cannot be represented in the current code page (1252)
ここの 1252 は Windows-1252 - Wikipedia のことを指します.
どうもロケールを変えてcode pageを今回ではSJISの932に変えてあげる必要がありそうです.
やり方は流石にAppVeyorとかのドキュメントに書いてあるだろうと思ったのですが,実際載ってなくてIssueを漁っていたら発見できました.
Support a different code page · Issue #846 · appveyor/ci · GitHub
日本語環境では
init: - ps: Set-WinSystemLocale ja-JP - ps: Start-Sleep -s 5 - ps: Restart-Computer
こんな感じです.
ちなみにこのStart-Sleep
を抜くと処理が返ってきません(このCIを回して他の作業をしていたのですが通知がこなくて見てみたら止まっていましたw)
こんな感じで日本語を含むプロジェクトでもAppVeyorでいい感じにビルドできそうです.
このミスに気づくのに数日かかったの本当に辛いお気持ちです…