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

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

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

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

C#

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

Q&A

解決済

2回答

4569閲覧

FelicaLibを用いて学生証を読み取りたい

dodome_iro

総合スコア14

DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

C#

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

0グッド

0クリップ

投稿2018/11/17 13:39

前提・実現したいこと

プログラム初心者です。
VisualStudio2017を使っています。c#でFelicaLibを用いて学生証を読み取ろうとしています。
デバッグしてみると下記のコードのpasorip = pasori_open(null);で例外がスローされてしまい読み取れません。

発生している問題・エラーメッセージ

PInvoke 関数 'ConsoleApp1!FelicaLib.Felica::pasori_open' がスタックを不安定にしています。PInvoke シグネチャがアンマネージ ターゲット シグネチャに一致していないことが原因として考えられます。呼び出し規約、および PInvoke シグネチャのパラメーターがターゲットのアンマネージ シグネチャに一致していることを確認してください。

該当のソースコード

using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace FelicaLib { // システムコード enum SystemCode : int { Any = 0xffff, // ANY Common = 0xfe00, // 共通領域 Cyberne = 0x0003, // サイバネ領域 Edy = 0xfe00, // Edy (=共通領域) Suica = 0x0003, // Suica (=サイバネ領域) } public class Felica : IDisposable { [DllImport("felicalib.dll", EntryPoint = "pasori_open", CallingConvention = CallingConvention.StdCall)] private extern static IntPtr pasori_open(String dummy); [DllImport("felicalib.dll", EntryPoint = "pasori_close", CallingConvention = CallingConvention.StdCall)] private extern static void pasori_close(IntPtr p); [DllImport("felicalib.dll", EntryPoint = "pasori_init", CallingConvention = CallingConvention.StdCall)] private extern static int pasori_init(IntPtr p); [DllImport("felicalib.dll", EntryPoint = "felica_polling", CallingConvention = CallingConvention.StdCall)] private extern static IntPtr felica_polling(IntPtr p, ushort systemcode, byte rfu, byte time_slot); [DllImport("felicalib.dll", EntryPoint = "felica_free", CallingConvention = CallingConvention.StdCall)] private extern static void felica_free(IntPtr f); [DllImport("felicalib.dll", EntryPoint = "felica_getidm", CallingConvention = CallingConvention.StdCall)] private extern static void felica_getidm(IntPtr f, byte[] data); [DllImport("felicalib.dll", EntryPoint = "felica_getpmm", CallingConvention = CallingConvention.StdCall)] private extern static void felica_getpmm(IntPtr f, byte[] data); [DllImport("felicalib.dll", EntryPoint = "felica_read_without_encryption02", CallingConvention = CallingConvention.StdCall)] private extern static int felica_read_without_encryption02(IntPtr f, int servicecode, int mode, byte addr, byte[] data); private IntPtr pasorip = IntPtr.Zero; private IntPtr felicap = IntPtr.Zero; public Felica() { pasorip = pasori_open(null); if (pasorip == IntPtr.Zero) { throw new Exception("felicalib.dll を開けません"); } if (pasori_init(pasorip) != 0) { throw new Exception("PaSoRi に接続できません"); } } public void Dispose() { if (pasorip != IntPtr.Zero) { pasori_close(pasorip); pasorip = IntPtr.Zero; } } ~Felica() { Dispose(); } public bool Polling(int systemcode) { felica_free(felicap); felicap = felica_polling(pasorip, (ushort)systemcode, 0, 0); if (felicap == IntPtr.Zero) { return false; //throw new Exception("カード読み取り失敗"); } return true; } public byte[] IDm() { if (felicap == IntPtr.Zero) { throw new Exception("no polling executed."); } byte[] buf = new byte[8]; felica_getidm(felicap, buf); return buf; } public byte[] PMm() { if (felicap == IntPtr.Zero) { throw new Exception("no polling executed."); } byte[] buf = new byte[8]; felica_getpmm(felicap, buf); return buf; } public byte[] ReadWithoutEncryption(int servicecode, int addr) { if (felicap == IntPtr.Zero) { throw new Exception("no polling executed."); } byte[] data = new byte[16]; int ret = felica_read_without_encryption02(felicap, servicecode, 0, (byte)addr, data); if (ret != 0) { return null; } return data; } } }

試したこと

StdCallではなくCdeclを使用してみましたが、pasorip == IntPtr.Zeroとなっているようで"felicalib.dll を開けません"が表示されるため結局は学生証が読み取れませんでした。

補足情報(FW/ツールのバージョンなど)

dllファイルの位置は実行ファイルと同じです。

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

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

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

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

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

guest

回答2

0

ベストアンサー

プログラムのコードと言うより、動作環境やfelicalib(FeliCa Library)のバージョンが不適切なのではないかな、と思えます。

こちらで試してみたところではWindows 7(64ビット)およびWindows 10(64ビット)上でパソリRC-S380を接続し、特に問題なくfelicalib を使うことができました。質問者さんのお使いのWindowsのバージョンやパソリのリーダーライターの機種名が示されていないので不確かな面がありますが、ひとつひとつ確認してみてください。

SONYから提供されるパソリのドライバー「NFCポートソフトウェア」は正しくインストールされていますか。これをインストールすると、「NFCポート自己診断」と言うアプリケーションが使えるので、これでリーダーライターであるパソリとFeliCaのICカードが正しく使えるか確認してください。まずこれが大前提です。

felicalib(FeliCa Library)はオリジナルの開発者の方がgithub上で公開されているものを含め、いくつかバージョンがあるようです。github上の最新のソースはかなりアップグレードされているので、簡単に、以下のようにfelicalib-0.4.2を使って試してみているので参考にしてください。

まず、https://github.com/tmurakam/felicalib/releases のfelicalib-0.4.2 のzipファイルをダウンロードし、展開します。

次に、もともとがVisual Studio 2008用のソリューションファイルであるfelicalib-0.4.2\src\CSharp\CSharp.sln をVisual Studio 2017 で開きます。
プロジェクトはVisual Studio 2017用にコンバートされますので、そのままビルドします。

src\CSharp\bin\x86\Debug\ 下に、ZIPファイルに同梱のfelicalib.dll を配置します。felicalib.dllは再ビルドしなくてもそのまま使えました。

src\CSharp\Sample.csはnanacoのブロックを読み出すものなので、ポーリングでFeliCa のIDmを読むだけのものに修正して動作を確認します。

C#

1// src\CSharp\Sample.cs の一部 2public static void Main() 3{ 4 try 5 { 6 using (Felica f = new Felica()) 7 { 8 // nanacoのブロックを読み出すコードなので、無効化 9// readNanaco(f); 10 11 // システムコードをワイルドカード指定(0xffff)でカードをポーリング 12 f.Polling((int)SystemCode.Any); 13 14 // IDm をダンプ 15 Console.Write("IDm: "); 16 byte[] idm = f.IDm(); 17 foreach (byte b in idm) 18 { 19 Console.Write(string.Format("{0:X2} ", b)); 20 } 21 Console.WriteLine("\nDone"); 22 } 23 } 24 catch (Exception ex) 25 { 26 Console.WriteLine(ex.Message); 27 } 28}

これで少なくともFeliCaのカードIDであるIDmは読めるはずです。(質問者さんの学生証特有のデータ読み取りは、別の話となるので割愛します)

もし、felicalib-0.4.2でC#のプロジェクトを新規作成するときはプラットフォームをWin32ネイティブのDLLであるfelicalib.dllに合わせる必要があるので、注意してください。上記の例ではx86です。

プラットフォーム指定

尚、github上の最新のソースではAny CPUで使えるよう、x86動作かx64動作か自動判別して使えるようアップグレードされていました。

以上、ご参考になれば。

投稿2018/11/18 03:38

dodox86

総合スコア9183

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

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

dodome_iro

2018/11/18 15:41

とても詳しく教えていただきありがとうございました。 ドライバーが正しくインストールされていないためdllファイルが開くことができなかったようです。
guest

0

まず、学生証が読めるかどうかよりも、SuicaなどのFelicaカードを読んでみましょう。
# その学生証というのははたしてFelicaで読めるのか?という疑問が

そのまんま、「felicalib.dll」でぐぐるとVB.NETやC#のコードが出てくるので参考にしてみてはどうでしょう

投稿2018/11/17 13:48

編集2018/11/17 13:49
y_waiwai

総合スコア87774

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

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

dodome_iro

2018/11/17 14:02

回答ありがとうございます。色々参考にしてみます。 学生証はFelicaで読み取ることはできます。 フリーソフトを使用して読み取れるか試してみたところ、学生証内のICチップの情報が16進数ではありますが表示することができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問