トップ回答者
midiOutOpenができません

質問
-
初めて質問させていただきます。
当方、C/C++はかじったことがあるのですがVisual C++は初心者です。
Windows Vista Home Premium で Visual C++ Express Edition を使用しています。
Form1でピアノの鍵盤のような画面を作り、鍵盤をクリックすると音が鳴る、というものを作っているところなのですが、
midiOutOpen()の戻り値が「MMSYSERR_INVALPARAM 指定されたポインタまたは構造体は無効です。」となり、
音が出ません。
ググってみると、midiOutOpen()の第一引数は「HMIDIOUT型へのポインタ」となっているものと、
「LPHMIDIOUT型」となっているものと、両方出てくるので(この2つは同じ意味なのでしょうか?)両方試してみたところ、
以下のようになりました。
前者のケース↓
//変数宣言
HMIDIOUT hMidiOut;
(略)
//MIDIオープン
int ret; //midiOutOpen関数の戻り値
ret = midiOutOpen(&hMidiOut,-1,0,0,0);
//↑ または ret = midiOutOpen(this->hMidiOut,-1,0,0,0);
[コンパイルエラー]
error C2664: 'midiOutOpen' : 1 番目の引数を 'HMIDIOUT' から 'LPHMIDIOUT' に変換できません。(新しい機能 ; ヘルプを参照)
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。後者のケース↓
//変数宣言
LPHMIDIOUT lphMidiOut;
(略)
//MIDIオープン
int ret; //midiOutOpen関数の戻り値
ret = midiOutOpen(lphMidiOut,-1,0,0,0);
[結果]
コンパイルは通るが、ret=11=MMSYSERR_INVALPARAM (指定されたポインタまたは構造体は無効)になる
ちなみにまったく同じプログラムをVisual Vasic 2005(こちらはExpress Editionではなく正規版です)で作ったところ、
問題なく音が鳴りました。
どうすればmidiOutOpen が正常にできるのか、教えて頂ければ幸いです。
宜しくお願い致します。
長文失礼致しました。
回答
-
yu_taki さんからの引用 ret = midiOutOpen(&hMidiOut,-1,0,0,0); と書いたとき↓
[コンパイルエラー]
error C2664: 'midiOutOpen' : 1 番目の引数を 'cli::interior_ptr<Type>' から 'LPHMIDIOUT' に変換できません
hMidiOutをrefクラスのメンバ変数にしていませんか?(たとえばForm1のメンバ変数とか)
(メンバ変数なら m_hMidiOut とか hMidiOut_ とかわかるようにしてもらいたいです。)
pin_ptrを使ってピン止めしてあげてから渡すとどうなりますか?
以下実験したコードSample#include <windows.h> // 実験用関数 void __stdcall Hoge(LPHMIDIOUT l) { *l = (HMIDIOUT)0x1; // 値が設定されたか確認用 } value struct AAA { HMIDIOUT hMidiOut; }; ref struct BBB { HMIDIOUT hMidiOut; }; int main() { // ローカル変数 HMIDIOUT hMidiOut = NULL; Hoge(&hMidiOut); // valueクラスのメンバ AAA a; a.hMidiOut = NULL; Hoge(&a.hMidiOut); // refクラスのメンバ BBB b; b.hMidiOut = NULL; // Hoge(&b.hMidiOut); C2664 pin_ptr<HMIDIOUT> p = &b.hMidiOut; Hoge(p); return 0; }
すべての返信
-
> ちなみにまったく同じプログラムをVisual Vasic 2005(こちらはExpress Editionではなく正規版です)で作ったところ、
> 問題なく音が鳴りました。
Visual Studio 2005?(Std/ProのC++?)
Visual Basic 2005?(Std/Pro)
midiOutOpenってWin32 APIの関数ですよね?
Platform SDKがインストールされていないんじゃないですかね。
Express Editionでダメってことなら。
http://www.cppdrive.jp/vc/sdk/
http://freepg.fc2web.com/cpp/topic_vce_001.html -
>ぼーずさん
さっそくの回答ありがとうございます。
スペルミス、、、(笑)すみません。
Visual Studio 2005 の Visual Basic です。
ビルド、実行ともにまったく同一のPCでやりました。
先ほど、Visual Studio 2005 (正規版)の中のC++でビルドしてみたところ、
やはりmidiOutOpenの戻り値が11になってしまいました。
(ややこしくなってすみません。現在、同じPCの中に、
・VB(正規版)でビルドしたもの:音が出る
・VC++(正規版)でビルドしたもの:音が出ない
・VC++(Express Edition)ででビルドしたもの:音が出ない
の、3つがあることになります。VC++の2つは同一のプロジェクトを正規版とExpressの双方から開いたものです)
winmm.libはリンク済みです。
SDKはまだ確認していないのですが、調べてまた書き込みます。
取り急ぎ失礼します。
-
前者のケースがコンパイルが通らないのってのがおかしいですね。
後者のケースは間違いです。
実体がないポインターを渡しているのでMMSYSERR_INVALPARAMになります。
これ、コンパイル通ったコードをそのまま貼り付けてます。
HMIDIOUT hMidiOut;
int ret = midiOutOpen(&hMidiOut,-1,0,0,0);
「1 番目の引数を 'HMIDIOUT' から 'LPHMIDIOUT' に変換できません。」
ってエラーからして、単に参照演算子(&)をつけ忘れてたんじゃないかと思うのですが。
○: &hMidiOut
×: hMidiOut -
>ぼーずさん
書き込み有難うございます。ここ数日ネットに接続できない環境におりまして、レスが遅れてすみませんでした。
試しに、「&hMidiOut」と「hMidiOut」両方でコンパイルしてみました。
以下のようになりました。
ret = midiOutOpen(&hMidiOut,-1,0,0,0); と書いたとき↓
[コンパイルエラー]
error C2664: 'midiOutOpen' : 1 番目の引数を 'cli::interior_ptr<Type>' から 'LPHMIDIOUT' に変換できません
ret = midiOutOpen(hMidiOut,-1,0,0,0); と書いたとき↓
[コンパイルエラー]
error C2664: 'midiOutOpen' : 1 番目の引数を 'HMIDIOUT' から 'LPHMIDIOUT' に変換できません
今日気づいて気になったのですが、winmm.libはリンク済み、と書きましたが、
後者のケースでコンパイルが通る場合、デバッグ時の出力に
「~が読み込まれました。シンボルは読み込まれませんでした。」と表示される中に、
「~winmm.dllが読み込まれました。」とは出てこないのです。。。
うまくリンクできていないということなのでしょうか???
-
yu_taki さんからの引用 ret = midiOutOpen(&hMidiOut,-1,0,0,0); と書いたとき↓
[コンパイルエラー]
error C2664: 'midiOutOpen' : 1 番目の引数を 'cli::interior_ptr<Type>' から 'LPHMIDIOUT' に変換できません
hMidiOutをrefクラスのメンバ変数にしていませんか?(たとえばForm1のメンバ変数とか)
(メンバ変数なら m_hMidiOut とか hMidiOut_ とかわかるようにしてもらいたいです。)
pin_ptrを使ってピン止めしてあげてから渡すとどうなりますか?
以下実験したコードSample#include <windows.h> // 実験用関数 void __stdcall Hoge(LPHMIDIOUT l) { *l = (HMIDIOUT)0x1; // 値が設定されたか確認用 } value struct AAA { HMIDIOUT hMidiOut; }; ref struct BBB { HMIDIOUT hMidiOut; }; int main() { // ローカル変数 HMIDIOUT hMidiOut = NULL; Hoge(&hMidiOut); // valueクラスのメンバ AAA a; a.hMidiOut = NULL; Hoge(&a.hMidiOut); // refクラスのメンバ BBB b; b.hMidiOut = NULL; // Hoge(&b.hMidiOut); C2664 pin_ptr<HMIDIOUT> p = &b.hMidiOut; Hoge(p); return 0; }