C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: CreateEventが失敗する


(過去ログ 108 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■64563 / inTopicNo.1)  CreateEventが失敗する
  
□投稿者/ tonn (6回)-(2012/12/07(Fri) 11:45:02)

分類:[VB.NET/VB2005 以降] 

※すいません、さきほど途中送信してしまい編集しようとしましたがうまくいかないため再投稿させて頂きます。

先日VB6からVB2005への変換で別の構造体のメンバが同時に変化する問題を質問させて頂いた者です。
その節はどうもありがとうございました。

今回別の問題を質問させて頂きます。

RS232C通信にAPIのCreateEventを使ってるところがあり、そこでひっかかるのですが、ソースは単純化すると下記のような感じです。

'APIの宣言
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, ByVal lpSecurityAttributes As Integer, ByVal dwCreationDisposition As Integer, ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As Integer) As Integer

Public Declare Function SetCommMask Lib "kernel32" (ByVal hFile As Integer, ByVal dwEvtMask As Integer) As Integer

Public Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (ByRef lpEventAttributes As Integer, ByVal bManualReset As Integer, ByVal bInitialState As Integer, ByVal lpName As String) As Integer

'232Cオープンの関数
Public Function G_CommOpen(ByRef intCommCh As Short) As Short
        '
        ' 機能     : ポートのオープン
        '
        ' 返り値   :  0 - 正常
        '         -1 - オープン出来ない(エラー)
        '
        ' 引き数   : intCommCh - オープンするポート番号
        '
        ' 機能説明 : intCommCh で指定された COMポートをオープンします。
        '
        If G_CommHandle(intCommCh) = INVALID_HANDLE_VALUE Or G_CommHandle(intCommCh) = 0 Then
            'オープンしてないポートのハンドルは、INVALID_HANDLE_VALUEに設定する
            G_CommHandle(intCommCh) = INVALID_HANDLE_VALUE
        Else
            '既にオープン済みの場合は Exit
            G_CommOpen = 1
            G_lngLastErr = NO_ERROR
            Exit Function
        End If

        'ポートのオープン
        G_CommHandle(intCommCh) = CreateFile(G_COMM_PORTNAME & intCommCh, GENERIC_READ Or GENERIC_WRITE, &H0S, &H0S, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, &H0S)

        If G_CommHandle(intCommCh) = INVALID_HANDLE_VALUE Then
            'ハンドルの取得に失敗したら、エラーの内容を確認する
            MsgBox(GetLastError)
            'Call G_GetCommErrMsg("G_CommOpen()のCreateFile()")
            G_CommOpen = -1
            Exit Function
        End If

        '監視するイベントを設定
        If Not CBool(SetCommMask(G_CommHandle(intCommCh), EV_MASK)) Then
            MsgBox(GetLastError)
            'Call G_GetCommErrMsg("G_CommOpen()のSetCommMask()")
        End If

        '受信用OVERLAPPED構造体を設定
        lngReadHandle(intCommCh) = CreateEvent(&H0S, True, False, CStr(&H0S))
        If lngReadHandle(intCommCh) = 0 Then
          MsgBox(GetLastError)
        Call G_GetCommErrMsg("G_CommOpen()のlngReadHandle=CreateEvent()")
        End If


        'ハンドルを取得できたら、エラーなし
        G_CommOpen = 0

    End Function

'呼び出し元
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        G_CommOpen(6)
    End Sub

以上を実行すると

lngReadHandle(intCommCh) = CreateEvent(&H0S, True, False, CStr(&H0S))

の所でCreateEventが失敗します。GetLastErrorで見るとエラーコード1305となります。
1305はERROR_UNKNOWN_REVISIONのようです。

ここで
lngReadHandle(intCommCh) = CreateEvent(&H0S, True, False, CStr(&H0S))
以後を別の関数に分離しG_CommOpenSubとし、呼び出し元を

G_CommOpen(6)
G_CommOpenSub(6)

としてやると何故かエラーしません。
エラーしないのでいいかと保留にして進めたのですが、結局デバッグ環境ではよかったのですが、コンパイルしたEXEではこのエラーが再発してしまいました。

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

引用返信 編集キー/
■64571 / inTopicNo.2)  Re[1]: CreateEventが失敗する
□投稿者/ 774RR (33回)-(2012/12/07(Fri) 16:45:08)
俺 VB は使わない人なんだけど
・なぜに SerialPort クラスを使わないのか(既存コードとの互換性が優先?)
 たぶん SerialPort クラス使うほうが圧倒的に簡単だと思う
・なぜに CreateEventA なのか CreateEventW にしない理由は
 同様 CreateFileW にしない理由とか
・そのコードで COM10 以上に対応できてるのかな

とかそういうことを思ったりした。

ネイティブコードを使いたい、特に Win32 API の直接呼出しがしたいのであれば
C++/CLI あたりで DLL にくるんでしまうほうがよほど簡単だと思うし
どうせマネージコードに書き換えちゃうなら、全面的に SerialPort に移行するほうが
後腐れなくてよさそうな気のせいがする。

んで俺はネイティブ系はわかるけど VB はよく知らない人なので、後は皆様にお任せ。
引用返信 編集キー/
■64573 / inTopicNo.3)  Re[2]: CreateEventが失敗する
□投稿者/ tonn (7回)-(2012/12/07(Fri) 17:42:19)
自己解決しました。
APIの宣言が違ってたようです。
VB2005の変換ウイザードが変換したままにしてたのですが、CreateEventの第一引数はByRefではなくByValだったようです。
下記資料の「4.3.8 イベントオブジェクト」を参考にしました。

http://www.interface.co.jp/download/tutorial/tut0014_33.pdf

>>774RR様
ありがとうございます。
言われることはよく分かります、232CはSerialPort使うのもC++でDLLを自作するのもやったことがあるので。
ただ、今は既存のVB6ソースの.NET移植と仕様変更なので、、、
このソースの担当は私が3人目で前任の2人は既に居ないので中身がよく分からないため、今のところ出来るだけ元のソースを活かす方向でやってます。

でもAPI使ってるとことかはひっかかりまくって大変です(^^;
.NETとAPIの組み合わせはWEB情報も少ないし、、、6までと違ってあまり必要性がないせいだと思いますが。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -