DOBON.NET DOBON.NETプログラミング掲示板過去ログ

C#からC++DLLへ

  • 題名: C#からC++DLLへ
  • 著者: ひかり
  • 日時: 2007/04/04 19:18:51
  • ID: 19432
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[WindowsXP Pro SP2 / VS2005Pro / .Net Framework2.0]
分類:[.NET]

いつもいろいろと参考にさせて頂いております。

現在C#でアプリを書いておりまして
それにC++で作成したDLLを読み込ませ、
C#アプリからウインドウズハンドルを
渡そうとしているのですがうまく渡せません、、、。

C#側(TEST.exe)----------------------------
class ImportdDll
{
[DllImport("jisaku.dll")]
unsafe public extern static byte* kansu(IntPtr hwnd);
}

unsafe private void btn_Click_1(object sender, EventArgs e){
IntPtr gethandle = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;

byte* testreturn = (byte*)ImportdDll.kansu(gethandle);
}

C++DLL側(jisaku.dll)----------------------
EXPORT BOOL WINAPI kansu(HWND hwnd)
{
(略)
return true;
}
------------------------------------------
そのまま実行すると
エラー内容--------------------------------
'System.AccessViolationException' のハンドルされていない例外がTEST.exe で発生しました。

追加情報: 保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。
------------------------------------------
と言われてしまいます。
確認したことは、C#側からDLL側へは確かに何らかの同じ値が渡っています。
具体的にはgethandle="0x0002092c"といった値でこのメモリは
exeファイルのファイルパスの途中をさしてました。
(おそらくでたらめなアドレスなのだと思います)
あとウインドウハンドルを取ってくるのにFindWindowも使いましたが
結果は同じでした。
(DLL内からもFindWindowで取ってみましたが同じ値を指してました)

ネット上を結構探したのですがウインドウハンドルを取るようなことを
してることが少なくなかなか思うように取って来れません。
(もしかすると根本的にC#の扱い方を間違ってる?)
C#は初心者でよく分からず、かなりハマってて参ってます。。。
どなたかヒントになるようなことでも構いませんので教えて頂ければと思います。
また設定などの情報が不足しているようでしたら書き込みますので
指示して頂ければと思います。
以上、よろしくお願いします。
> C#アプリからウインドウズハンドルを

何ゆえに複数形?
正しい用語を使いましょう。

> 渡そうとしているのですがうまく渡せません、、、。

ぱっと見ですぐ気づくのは

> [DllImport("jisaku.dll")]
> unsafe public extern static byte* kansu(IntPtr hwnd);



> EXPORT BOOL WINAPI kansu(HWND hwnd)

では、明らかに食い違っていることです。
もう少し検証する部分はあるとは思いますが、とりあえず気づいたところだけ。

(1) C# 側で IntPtr を使っているのに、なぜ C++ 側では HWND を使っているのでしょうか
(2) C++ 側の戻り値が BOOL であるのに対し、C# 側が byte* なのはなぜでしょうか。

> (もしかすると根本的にC#の扱い方を間違ってる?)

意外とそんな気がします。
これだけを見ると、失礼ですが C++ の方も怪しいような。

# ひどりさんに先を越されてしまいました…
返信ありがとうございます。

■No19433に返信(渋木宏明(ひどり)さんの記事)
>>C#アプリからウインドウズハンドルを
>
> 何ゆえに複数形?
> 正しい用語を使いましょう。

失礼しました(^^;

>>[DllImport("jisaku.dll")]
>>unsafe public extern static byte* kansu(IntPtr hwnd);
> と
>>EXPORT BOOL WINAPI kansu(HWND hwnd)
> では、明らかに食い違っていることです。

C/C++でのHWNDをC#で扱うのはIntPtrでよいですよね?
となるとBOOLの関数をbyte*で受けてるのがよくない?
引数ばかりに目がいっててそちらは気にしてませんでした、、。
  • 題名: Re[3]: C#からC++DLLへ
  • 著者: ひかり
  • 日時: 2007/04/04 20:23:56
  • ID: 19436
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
返信ありがとうございます。

> もう少し検証する部分はあるとは思いますが、とりあえず気づいたところだけ。
> (1) C# 側で IntPtr を使っているのに、なぜ C++ 側では HWND を使っているのでしょうか

もともとは別のC++のアプリからこのDLLを読み込ませてそこで
HWNDを渡していたためこのようになってます。

> (2) C++ 側の戻り値が BOOL であるのに対し、C# 側が byte* なのはなぜでしょうか。

BOOLに対する戻り値としてbyteが適してると(勝手に)思ってそのポインタが
欲しいのでbyte*としました。

>>(もしかすると根本的にC#の扱い方を間違ってる?)
> 意外とそんな気がします。
> これだけを見ると、失礼ですが C++ の方も怪しいような。

うぅ、、もろに見透かされてしまいましたね(^^;;;
確かにC++も別に熟練というわけではなくC言語がやっとの者です、、。
やさしい目で見て頂けるとありがたいです。

なんだかウインドウハンドル以前の部分で怪しいところもありそうかなぁ?
2007/04/04(Wed) 20:29:38 編集(投稿者)

> (1) C# 側で IntPtr を使っているのに、なぜ C++ 側では HWND を使っているのでしょうか

これはそういうもんです。
C++/CLI じゃなさそうなんで。
> となるとBOOLの関数をbyte*で受けてるのがよくない?

よくないです。

おそらく、「C++ の bool は1バイト」のような聞きかじりの知識が頭の隅にでもあったんでしょうね。

BOOL の定義を SDK のヘッダで確認すれば分かることですが、大文字の BOOL は C/C++ 的には int です。

なので、BOOL を int に見立てた P/INVOKE 宣言を書けば、一応は動作します。

ですが、ヘルプに記載があるはずですが、.NET のマーシャリング規則では BOOL = int を C# の bool にデフォルトでマーシャリングしてくれます。

なので

BOOL hoge(HWND hwnd);



[DllImport(適宜)]
static extern bool hoge(IntPtr hwnd);

でよいことになります。
■No19438に返信(渋木宏明(ひどり)さんの記事)
> BOOL の定義を SDK のヘッダで確認すれば分かることですが、大文字の BOOL は C/C++ 的には int です。
> なので、BOOL を int に見立てた P/INVOKE 宣言を書けば、一応は動作します。
> ですが、ヘルプに記載があるはずですが、.NET のマーシャリング規則では BOOL = int を C# の bool にデフォルトでマーシャリングしてくれます。
> BOOL hoge(HWND hwnd);
> は
> [DllImport(適宜)]
> static extern bool hoge(IntPtr hwnd);
> でよいことになります。

なるほど、そういうマーシャリング規則があるのですね(^^;;
改めてこの辺りから自分でも確認してみることにしました。
大変参考になります。
ありがとうございますm(__)m
■No19437に返信(渋木宏明(ひどり)さんの記事)

>>(1) C# 側で IntPtr を使っているのに、なぜ C++ 側では HWND を使っているのでしょうか
>
> これはそういうもんです。
> C++/CLI じゃなさそうなんで。

ああそうか、そういえば HWND は IntPtr を使いますもんね。
すいません。そこはちょっと勘違いしてました。

結局のところ戻り値 BOOL を byte* で受けようとしてたのが原因
だったのかな。
# 正直、unsafe なんてあんまり使わないよなぁと気になってましたが。

DOBON.NET | プログラミング道 | プログラミング掲示板