objective-cをちょい研究!ブログ -45ページ目

objective-cをちょい研究!ブログ

WILLCOMを卒業してiOS開発者に転身しました。。
コメント&トラックバック大歓迎です。

VBだと作りやすいんですが何かと制約が多いので、

C++でDLLを作成してVBでそのDLLを参照する方法のメモです。


1.C++でDLLプロジェクトを作成する。

テンプレート
 Visual C++ -> スマートデバイス -> Win32 スマートデバイスプロジェクトを選択


プロジェクト設定|アプリケーションの種類
 DLL(D)を選択


公開する関数宣言をhファイルに追加(例えばstdafx.hの最後)

#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void fncTest(void); //VBから参照したい関数宣言
#ifdef __cplusplus
}
#endif

extern "C"
 C++だと同一関数名の識別のため変な関数名になってしまうので、そのままの関数名で公開。
__declspec(dllexport)
 DLLからエクスポートするための修飾子


cppファイルに追加

__declspec(dllexport) void fncTest(void)  //VBから参照したい関数
{
  return;
}

2.VBから作成したDLLを参照する。

  <DllImport("\Program Files\test\test.dll")> _
  Private Shared Sub fncTest()
  End Sub


  Sub subTest()
    fncTest()
  End Sub


ちなみに、C#から作成したDLLを参照する場合

  [DllImport("\\Program Files\\test\\test.dll")]
  private static extern void fncTest();


__declspec(dllexport)について
http://hp.vector.co.jp/authors/VA023539/tips/dll/001.htm

extern "C"について
http://1024x768.blog74.fc2.com/blog-entry-31.html

随分Zero3のDLLが解析されてると思ったら、こんなソフトあるんですね。
DLLファイルに含まれる関数名をリストアップしてくれます。
http://www.mozilla-japan.org/quality/help/dependency-walker.html


英語版ですが使い方も簡単で、DLLファイルをドロップするだけで使えました。
さらに、メニューの[View|Undecorate C++ Functions]を選ぶと、C++DLLの場合、
クラス名や引数まで解析してくれます。


たとえばZero3のWindowsフォルダにあるshphonelib.dllで試してみると、

??0CshphoneClientlib@@QAA@PAUHWND__@@H@Z
↓こんな感じ
CshphoneClientlib::CshphoneClientlib(struct HWND__ *,int)

ソフト整理により、公開終了です。


課題の2点が解決したので、実行ファイルをアップしておきます。
http://www.ne.jp/asahi/phs/phs/blog/adeskeybord.lzh  


LZHファイルを解凍して、EXEファイルを好きなフォルダに置いて実行して下さい。

1~8キーでド~ドが鳴ります。一応和音も出せます。音に合わせてLEDが点灯します。
ソフトキー1でアプリケーション終了です。


実行画面も無地、タイトルもデフォルトのまんまなので
需要があればちゃんとしたもの作ります。

#せっかく書き込んでもらった書き込みですが、誤って削除してしまいましたm(_._)m


Midi関連部分のソースと実行ファイルをアップしました。音はものすごい悪いです(^^;
http://www.ne.jp/asahi/phs/phs/blog/midi080211.lzh


<課題1>
現状では数字キー入力に変更しないと音が鳴りません。
キー入力モードによって、KeyDownパラメータが変わってしまうので、
デフォルトで数字キー入力できるように改造中です。
レジストリ操作で変更できるようなのですが、C++の場合、WM_CREATE内で
入力モードを変更しても全角入力に戻ってしまいました。
PostMessageでワンクッション置いて変更するとうまくいくようです。


HKEY hKey;
BYTE szBuff[256];
DWORD PType, cb;


case WM_CREATE:
  PostMessage (hWnd, WM_COMMAND, 10000, 0);

case WM_COMMAND:

  if (wParam == 10000){
    if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Sharp\\PhoneStatus"),
      0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) {
      cb = sizeof(szBuff);
      if (RegQueryValueEx(hKey, _T("Status22"), 0, &PType,
        szBuff, &cb) == ERROR_SUCCESS){
        DWORD dNum = 7; //数字入力
        RegSetValueEx(hKey, _T("Status22"), 0, REG_DWORD,

          (LPBYTE)&dNum , sizeof(dNum ));
      }
      RegCloseKey(hKey);
    }

  }


ここら辺を参考させてもらいました。
http://d.hatena.ne.jp/annin102/20071122
  入力モードを _1 に変更する方法(闇忍日記様)


<課題2>
単に音が鳴るだけなのもつまらないので、音に合わせてLEDを光らせる。


http://blog.tauchi.net/2007/09/led.html
  LED制御(tauchi.net様)
http://blog.tauchi.net/2007/10/led.html
  電波状態LEDの制御(tauchi.net様)

Windows Mobile6 のAPIを使ってZero3キーボードの試作中です。
テンキーの1~8を押してる間だけド~ドを鳴らすというものです。


MIDI再生は以下のような4つの関数を作ってみました。最初にmidiOpenでMIDIポートを開き、KeyDownでmidiNoteOn、KeyUpでmidiNoteOff、最後にmidiCloseでMIDIポートを閉じます。
一応鳴らすことには成功したのですが、メモリ開放がうまくいってないようで、しばらく音を鳴らしていると途中で音が出なくなってしまいました(>_<)
そうなったら、アプリを再起動してもだめでアドエス自体を再起動するしかない…。
メモリ開放部分については、音が鳴り終わったあとにもmidiClose処理を入れるなど調整中です。

#include "wfmtmidi.h"


midiOpen()
  waveOutOpen(~) //MIDIポートオープン


midiNoteOn(noteNo)
  .DeltaTicks=0;
  .MidiMsg=0x7F0090 | (noteNo<<8); //ノートオンデータ作成
  waveOutPrepareHeader(~) //再生データ登録
  waveOutWrite(~) //再生
  WaitForSingleObject(~) //再生完了待ち
  waveOutUnprepareHeader(~) //再生データ開放


midiNoteOff(noteNo)
  .DeltaTicks=0;
  .MidiMsg=0x000080 | (noteNo<<8); //ノートオフデータ作成
  あとは midiNoteOn と同様


midiClose()
  waveOutReset(~) //出力全停止
  waveOutClose(~) //MIDIポートクローズ