質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows 7

Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Lua

Luaは、汎用のスクリプト言語の一つで、 移植性が高く、高速な実行速度などの特徴を持ち 手続き型・オブジェクト指向言語としても利用可能で 関数型言語、データ駆動型の要素も併せ持っている言語です。

Q&A

解決済

2回答

2073閲覧

Luaでファイル名にShift-JISの日本語を含むファイルを読み込むには?

port_san

総合スコア12

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows 7

Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Lua

Luaは、汎用のスクリプト言語の一つで、 移植性が高く、高速な実行速度などの特徴を持ち 手続き型・オブジェクト指向言語としても利用可能で 関数型言語、データ駆動型の要素も併せ持っている言語です。

0グッド

1クリップ

投稿2017/08/29 15:01

現在、Unity3Dでストーリー性があるゲームを作成しており、イベント管理をするためにNLua(Luaのバージョンは5.2)を使っています。
ゲームは、日本語を含むパスに置かれる場合も考えられ、また、Luaファイルにも日本語を使いたいと考えています。

しかし、luaファイルのパスに日本語を含む、または、ファイル名に日本語を含むファイル(以下、日本語ファイル)を
DoFileメソッドで読み込むことができませんでした。

以下、windows7で日本語ファイルの読み込みを検証したコードです。
ちなみにLua本体であるlua52.dllは
https://github.com/NLua/NLua
からソースコードをダウンロードしてVisual Stadio 2015でコンパイルして作成したものを使いました。

E:\えええ.lua

Lua

1Debug.Log( "hello".."aaa")

E:\test.lua

このファイルのみShift-JISで書いてあります。

Lua

1print("えええ") 2print("えええ") 3assert(loadfile[[E:\えええ.lua]])()

C#

1using NLua; 2using NUnit.Framework; 3 4public class LuaJapaneseTest { 5 6 Lua lua; 7 8 [SetUp] 9 public void SetUp() { 10 lua = new Lua(); 11 lua.LoadCLRPackage(); 12 lua.DoString("import 'UnityEngine'"); 13 14 } 15 16 [Test] 17 public void えええを読み込めるか() { 18 string filename = @"E:\えええ.lua"; 19 lua.DoFile(filename); 20 } 21 22 [Test] 23 public void ShitJISでファイル名を指定して読み込めるか() { 24 string filename = @"E:\test.lua"; 25 lua.DoFile(filename); 26 } 27}

実行結果

えええを読み込めるか [0.001s]

NLua.Exceptions.LuaScriptException : cannot open E:\えええ.lua: No such file or directory

at NLua.Lua.ThrowExceptionFromError (Int32 oldTop) [0x0003a] in G:\program\Assets\NLua\Lua.cs:365
at NLua.Lua.DoFile (System.String fileName) [0x00068] in G:\program\Assets\NLua\Lua.cs:530
at LuaJapaneseTest.えええを読み込めるか () [0x00006] in G:\program\Assets\Script\Editor\LuaScripts\LuaJapaneseTest.cs:19


となり、Shift-JISでファイル名を指定した場合のみ読み込みに成功します。

Ubuntu14.02 64bitで実行したときは、日本語ファイルを読み込むことが出来、
Windows7 64bitでは読み込むことが出来ませんでした。

以上のことから日本語ファイルを読み込めない原因は、Windowsのファイル名はShift-JISで、DoFileの引数で渡される文字列の文字コードが、C言語で書かれたLua本体で正しく認識されないことではないかと考えました。
そこで、

  • C#側で文字コードをShift-JISに変換して渡す
  • Lua側で受け取った文字列をShift-JISに変換する
  • C言語で受け取った文字列をShift-JISに変換する

という3つの方法が考えられます。

質問したい点は

  • そもそも、Windowsで日本語ファイルが読み込めないのはファイル名はShift-JISで、DoFileの引数で渡される文字列の文字コードが、C言語で書かれたLua本体で正しく認識されないからなのか
  • もし、そうなら、C#もしくはLua、C言語で文字コードを変換する(できればLuaかC#で)にはどうすればいいでしょうか。

です。

長文になってしまいましたが、回答よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

以下の方法で文字コードを変換してファイルにアクセすることが出来ました。

c#

1using NLua; 2using NUnit.Framework; 3using System.Text; 4using System.Linq; 5 6public class LuaJapaneseTest { 7 [Test] 8 public void Shif_JISに変換して読み込む() { 9 var lua = new Lua(); 10 lua.LoadCLRPackage(); 11 string filename = @"E:\えええ.lua"; 12 //NLuaで配列の要素に[]でアクセス出来ないのでリストに変換 13 var encodedByte = Encoding.GetEncoding(932).GetBytes(filename).ToList(); 14 15 string DoFileCode = @" 16-- 配列のインデックスの要素を呼び出す 17import 'UnityEngine' 18 19-- リストをテーブルに変換します。 20-- 引数にListを取ります 21local function arrayToTable(list) 22 local table = {} 23 for i = 1, list.Count, 1 do 24 table[i] = list[i - 1] 25 end 26 return table 27end 28 29return function(byteList) 30 local str = string.char( 31 table.unpack( 32 arrayToTable(byteList))) 33--文字コードを確認 34Debug.Log(table.concat(table.pack(string.byte(str, 1, #str)), ""-"")) 35 assert(loadfile(str))() 36end 37"; 38 var DoFile = (LuaFunction)lua.DoString(DoFileCode)[0]; 39 40 DoFile.Call(encodedByte); 41 } 42} 43

投稿2017/08/31 08:01

port_san

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

c#はしばらく触れていないし、NLuaというのもよく知りません。

そもそも、Windowsで日本語ファイルが読み込めないのはファイル名はShift-JISで、DoFileの引数で渡される文字列の文字コードが、C言語で書かれたLua本体で正しく認識されないからなのか

まぁおおよそそうですが一応補足を。

DoFileというのは、おそらく名前からしてluaのluaL_dofileを呼び出すラッパメソッドだと思います。
luaL_dofileは、ファイルをfopenを使用してアクセスしますが、ファイル名のエンコードは、環境に依存します。
VisualStudioであれば、MBCS(Windowsの言語による。日本語環境であれば、ShiftJIS)になります。

対して、C#の内部文字コードはUNICODEだったと思います。
だとすれば、おそらくluaにはUTF-8エンコードで渡されているのではないかと予想できます。

NLuaのページを見ると、DoStringというメソッドを使っています。
おそらく、luaL_dostringのラッパメソッドで、ファイルに書かれたスクリプトではなく、文字列をスクリプトとして実行するものかと思われますので、c#側でファイルよりスクリプトを読み込み、DoStringメソッドを呼んでスクリプトを実行するのが一番スマートかと思います。
こうすれば、ファイル名のエンコードは気にしなくて良いはずです。

投稿2017/08/30 13:16

katsuko

総合スコア3469

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問