🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
DLL

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

1回答

7636閲覧

VB.NETでPaSoRi(RC-S380)の操作 SCardGetStatusChangeでエラーが発生する。

Arsnova

総合スコア8

DLL

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2019/11/16 13:34

お世話になります。
Pasoriの操作で困っています。
下記問題、どうすれば回避できるでしょうか。

前提となる環境

  • Visual Studio 2015
  • Visual Basic
  • .NETFramework 4.6
  • PaSoRi(RC-S380)
  • 使用するライブラリ:WinSCard.dll

やりたいこと

一定間隔のループ処理の中で、カードがpasoriにかざされたら
そのIDを取得し、IDをキーとしていろいろ処理をしたい。

問題の箇所

SCardGetStatusChangeでエラーが発生する。

エラーの内容

マネージ デバッグ アシスタント 'PInvokeStackImbalance' が 'xxxxx.exe' で問題を検出しました。
追加情報:PInvoke 関数 'xxxxx.WinSCard+WinSCardWrapper::SCardGetStatusChange' がスタックを不安定にしています。
PInvoke シグネチャがアンマネージ ターゲット シグネチャに一致していないことが原因として考えられます。
呼び出し規約、および PInvoke シグネチャのパラメーターがターゲットのアンマネージ シグネチャに一致していることを確認してください。

エラー発生時のコード

■呼び出し元

VB

1Dim URtn As UInteger = WinSCardWrapper.SCardGetStatusChange(Me.hContext, -1, readerState, 1)

■定義側

VB

1 <DllImport("winscard.dll")> 2 Public Shared Function SCardGetStatusChange(ByVal hContext As IntPtr, 3 ByVal dwTimeout As Integer, 4 ByVal rgReaderStates As SCARD_READERSTATE, 5 ByVal cReaders As Integer) As UInteger 6 End Function

やってみたが解決しなかったこと

VB

1<DllImport("winscard.dll")> 2 3 ↓ 下のようにCallingConventionのパラメータを追加 4 5<DllImport("winscard.dll", CallingConvention:=CallingConvention.StdCall)>

その他

  • CallingConventionの値をどの値にしてもエラーが発生してしまいます。
  • ちなみにFastCallを指定した時は下記エラーが発生してしまいます。

System.TypeLoadException: 無効なアンマネージ呼び出し規約です。
stdcall、cdecl または thiscall のいずれかでなければなりません。

以上よろしくお願い致します。

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

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

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

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

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

y_waiwai

2019/11/16 14:06

winscard.dllのSCardGetStatusChange関数の定義はどうなってるんでしょうか
Arsnova

2019/11/16 14:33

ご連絡いただきありがとうございます。 winscard.dllはMicrosoftから提供されていて利用者側は中身を見れない認識です。 実際定義部分のSCardGetStatusChangeを[右クリック]→[定義に移動]をクリックしても 遷移しません。 認識間違いありましたらご指摘いただけると幸いです。
guest

回答1

0

「SCardGetStatusChangeW function」
https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardgetstatuschangew

rgReaderStates は SCARD_READERSTATE 構造体の配列のアドレスを渡すので

VB

1 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> 2 Public Structure SCARD_READERSTATE 3 <MarshalAs(UnmanagedType.LPTStr)> 4 Public szReader As String 5 Public pvUserData As IntPtr 6 Public dwCurrentState As Integer 7 Public dwEventState As Integer 8 Public cbAtr As Integer 9 <MarshalAs(UnmanagedType.ByValArray, SizeConst:=36)> 10 Public rgbAtr As Byte() 11 12 Public Sub New(ByVal reader As String) 13 szReader = reader 14 rgbAtr = New Byte(35) {} 15 End Sub 16 End Structure 17 18 <DllImport("winscard.dll", CharSet:=CharSet.Unicode)> 19 Public Shared Function SCardGetStatusChange( 20 ByVal hContext As IntPtr, 21 ByVal dwTimeout As Integer, 22 ByVal rgReaderStates As SCARD_READERSTATE(), 23 ByVal cReaders As Integer) As UInteger 24 End Function

使うときがちょっと面倒ですね。

VB

1 Dim lst As New List(Of SCARD_READERSTATE) 2 lst.Add(New SCARD_READERSTATE(reader1)) 3 lst.Add(New SCARD_READERSTATE(reader2)) 4 Dim arrays As SCARD_READERSTATE() = lst.ToArray() 5 Dim result As UInteger = SCardGetStatusChange(hContext, dwTimeout, arrays, lst.Count)

こんな感じになるかと。

投稿2019/11/16 16:37

編集2019/11/16 16:56
KOZ6.0

総合スコア2707

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

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

Arsnova

2019/11/17 06:37

ご回答ありがとうございます! ご相談させていただいていたエラーは解消されました。 1.SCardGetStatusChangeの第3引数に渡したSCARD_READERSTATEの値が   変わらない(dwEventStateでカードがタッチされたか判定したいが)ので、   定義をみたらByValになっていたので、ByRefに変えました。 2.SCardGetStatusChangeを実行したところ、戻り値が「2148532233」で   意味としては「UNKNOWN READER」が定数として表現されています。   ちなみに、   URtn = WinSCardWrapper.SCardGetStatusChange(Me.hContext, -1, arrays, lst.Count)   の実行時のarraysの中身は以下の通りです。   ・cbAtr:0   ・cbAtr:0   ・dwCurrentState:0   ・dwEventState:0   ・pvUserData:sizeは4     m_valueは&H00000000   ・rgbAtr:すべての要素0です。   ・szReader:"Sony FeliCa Port/PaSoRi 3.0 0" なにか解決策ありますでしょうか。 私の誤り等ございましたらご指摘ください。 よろしくお願いいたします。
KOZ6.0

2019/11/17 07:18

ByRef に変えてはだめだと思います。 値が変わらないというのは、lst を見ています?arrays ?
KOZ6.0

2019/11/17 07:46

リーダー名は正しいですか? SCardListReadersW https://docs.microsoft.com/ja-jp/windows/win32/api/winscard/nf-winscard-scardlistreadersw でリーダー名が取れるようです。 使い方は SCardLocateCardsW に書いてあるようです。 https://docs.microsoft.com/ja-jp/windows/win32/api/winscard/nf-winscard-scardlocatecardsw 私にできるのは、宣言を直すくらいです。 使ったことがないので使い方を聞かれてもわかりません。
Arsnova

2019/11/17 13:32

ありがとうございます。 YAmaGNZさんのおっしゃるサイトを参考にしています。このサイトでは、リーダー名がべた書きですが、 コードを修正して、SCardListReadersWを使ってリーダー名「Sony FeliCa Port/PaSoRi 3.0 0」が取得できているので正しいと思います。 修正する基準はKOZ6.0さんが上記でリンクを貼られたサイトを見ています。 C#のサイトをもっとよく見てみたいと思います。
KOZ6.0

2019/11/17 14:29 編集

LPCSTR szReader だから <MarshalAs(UnmanagedType.LPTStr)> は外すか UnmanagedType.LPStr にしたほうが良いかもしれません。 サンプルは宣言してないですし。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問