前提・実現したいこと
プログラム初心者です。
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ファイルの位置は実行ファイルと同じです。

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/18 15:41