プロが教えるわが家の防犯対策術!

win32api構造体引数の型指定について


selfesteemと申します。

midiを利用するアプリを作成するために
初めてwin32apiに挑戦しています。(WindowsVista,VB2008.net)

構造体引数の渡し方がまずいのかうまくいきません。

詳しい方教えていただけませんでしょうか?
よろしくお願いします。


・利用したいAPI
midiOutGetDevCaps

・発生するエラー
ArgumentException
型 'UInt32' のフィールド '_vDriverVersion' を持つ構造体のファイル入出力 (I/O) は無効です。


・MMSystem.hでの定義(抜粋)
WINMMAPI MMRESULT WINAPI midiOutGetDevCapsA( __in UINT_PTR uDeviceID, __out_bcount(cbmoc) LPMIDIOUTCAPSA pmoc, __in UINT cbmoc);

typedef UINT MMVERSION; /* major (high byte), minor (low byte) */
typedef struct tagMIDIOUTCAPSA {
WORD wMid; /* manufacturer ID */
WORD wPid; /* product ID */
MMVERSION vDriverVersion; /* version of the driver */
CHAR szPname[MAXPNAMELEN]; /* product name (NULL terminated string) */
WORD wTechnology; /* type of device */
WORD wVoices; /* # of voices (internal synth only) */
WORD wNotes; /* max # of notes (internal synth only) */
WORD wChannelMask; /* channels used (internal synth only) */
DWORD dwSupport; /* functionality supported by driver */
} MIDIOUTCAPSA, *PMIDIOUTCAPSA, *NPMIDIOUTCAPSA, *LPMIDIOUTCAPSA;


・実際のAPI呼び出しのソースコード(VB)

Imports System.Runtime.InteropServices

Private Declare Function midiOutGetDevCaps Lib "winmm.dll" Alias "midiOutGetDevCapsA" (ByVal uDeviceID As UInt32, _
ByRef lpCaps As MIDIOUTCAPS, _
ByVal uSize As UInt32) As Long

<StructLayout(LayoutKind.Sequential)> _
Structure MIDIOUTCAPS
Public wMid As Short
Public wPid As Short
Public _vDriverVersion As UInt32
<MarshalAs(UnmanagedType.LPTStr)> Dim szPname As String
Public wTechnology As Short
Public wVoices As Short
Public wNotes As Short
Public wChannelMask As Short
Public dwSupport As Long
End Structure

Sub main()
Dim ret As Long
Dim mc As New MIDIOUTCAPS
ret = midiOutGetDevCaps(0, mc, Len(mc))←ここでエラー
End Sub

A 回答 (1件)

VB.netは使ったことはありませんし、エラーの原因になる理由もわかりませんが…


気になったところを。

><MarshalAs(UnmanagedType.LPTStr)> Dim szPname As String
コレで、MAXPNAMELENバイトの領域になりますか?
この場合、APIから値を返されるコトになりますので、
http://akademeia.info/index.php?VB.NET%2F%A5%C6% …
で説明されている「VB.NETがAPIから文字列を受け取る場合はString型でもうまくいかない。」に関わる様な気がします。
そして、構造体のサイズ(バイト数)をmidiOutGetDevCaps()の第3引数に渡すことになりますが…
sizeof(MIDIOUTCAPSA)とLen(mc)は同じになるのでしょうか?
# APIの説明的には想定している構造体よりサイズが小さい場合は後ろのメンバは触られないみたいですが。
    • good
    • 0
この回答へのお礼

Wr5様

ご回答ありがとうございます!

UInt32 → Integer
<MarshalAs(UnmanagedType.LPTStr)>
→ <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=32)>

とすることで解決しました。大変助かりました。

お礼日時:2010/06/20 01:56

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!