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

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

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

Re[6]: SHFreeMallocの使い方


(過去ログ 14 を表示中)

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

■4741 / inTopicNo.1)  SHFreeMallocの使い方
  
□投稿者/ 倉田 有大 (24回)-(2007/06/23(Sat) 22:51:24)

分類:[C# (ASP.NET)] 

SHFreeMallocの使いかたを間違っていないか、教えてください。<__>

public static void SHFreeMalloc(IntPtr handle)
{
IMalloc alloc = null;
try
{
WindowsAPI.SHGetMalloc(out alloc);
Debug.Assert(alloc != null);
alloc.Free(handle);
// Free allocator itself
IUnknown iUnknown = (IUnknown)alloc;
iUnknown.Release();
System.Runtime.InteropServices.Marshal.ReleaseComObject(alloc);
}
}

上記の関数を

WindowsAPI.SHGetSpecialFolderLocation(Handle, shellSpecialFolder, out idHandle);
処理
SHFreeMalloc(idHandle)

上のようによんでいます。
この場合ReleaseComObjectは必要なのでしょうか?
昔、へんにReleaseを使ったときメモリーを??メガも食いまくったというわけのわからない症状もでて、
この使い方であっているのかわかりません。よろしくおねがいします。

引用返信 編集キー/
■4744 / inTopicNo.2)  Re[1]: SHFreeMallocの使い方
□投稿者/ 倉田 有大 (25回)-(2007/06/24(Sun) 13:39:55)
質問の仕方がわかりにくかったかな?^^;

WindowsAPI.SHGetMalloc(out alloc);
alloc.Free(handle);
IUnknown iUnknown = (IUnknown)alloc;
iUnknown.Release();
System.Runtime.InteropServices.Marshal.ReleaseComObject(alloc);

allocを取得して、リリースした後、ReleaseComObjectを呼び出す必要はあるのでしょうか?
COMのことがわかっておりません<__>
引用返信 編集キー/
■4797 / inTopicNo.3)  Re[2]: SHFreeMallocの使い方
□投稿者/ Atata!! (2回)-(2007/06/26(Tue) 00:07:52)
> allocを取得して、リリースした後、ReleaseComObjectを呼び出す必要はあるのでしょうか?

IMalloc を直接使用するのに妥当な理由が無いならば、
提示されている SHFreeMalloc の代わりに Marshal.FreeCoTaskMem を使用するべきです。
引用返信 編集キー/
■4853 / inTopicNo.4)  Re[3]: SHFreeMallocの使い方
□投稿者/ 倉田 有大 (29回)-(2007/06/27(Wed) 18:01:56)
No4797 (Atata!! さん) に返信
>>allocを取得して、リリースした後、ReleaseComObjectを呼び出す必要はあるのでしょうか?
>
> IMalloc を直接使用するのに妥当な理由が無いならば、
> 提示されている SHFreeMalloc の代わりに Marshal.FreeCoTaskMem を使用するべきです。

返信ありがとうございます。
FreeCoTaskMemを調べてみましたが、AllocCoTaskMemと一緒に使うのでしょうか?

IntPtr idHandle = IntPtr.Zero;
WindowsAPI.SHGetSpecialFolderLocation(Handle, shellSpecialFolder, out idHandle);
SHFreeMalloc(idHandle)

こんな感じで使っているのですが、

IntPtr idHandle = IntPtr.Zero;
WindowsAPI.SHGetSpecialFolderLocation(Handle, shellSpecialFolder, out idHandle);
Marshal.FreeCoTaskMem(idHandle);

これでいいということでしょうか?
COMは過去に何度か勉強したもののいまだにりかいしておりません。
質問ばかりで申し訳ない<__>
引用返信 編集キー/
■4867 / inTopicNo.5)  Re[4]: SHFreeMallocの使い方
□投稿者/ とっちゃん (153回)-(2007/06/27(Wed) 21:22:45)
とっちゃん さんの Web サイト
No4853 (倉田 有大 さん) に返信

SHGetSpecialFolderLocation じゃないとだめなんですか?
SHGetSpecialFolderPath とか、SHGetFolderPath とかではだめなのでしょうか?

こちらなら、IMalloc はいらないですよね?ITEMIDLISTじゃないとだめという場合もあるので
一概には言えませんが...

で、実装ですが、IMalloc が必要なのなら、その都度確保ではなく、最初に確保したら
以後ずっと使いまわしが基本です。もちろん STA でw

ちなみに、COMオブジェクトを開放するのに IUnknown を引っ張る必要はありません。
いらなくなった時点で
System.Runtime.InteropServices.Marshal.ReleaseComObject(alloc);
を呼び出すだけでOKです。

キャストした場合は、キャストしたオブジェクトごとに呼び出す必要があるはずです。
.NET では原則として IUnknown を必要とする処理はいらないはずです。
#もちろん、メソッドとしてのAddRef/Releaseも含め

引用返信 編集キー/
■4870 / inTopicNo.6)  Re[5]: SHFreeMallocの使い方
□投稿者/ 倉田 有大 (31回)-(2007/06/27(Wed) 22:04:21)
No4867 (とっちゃん さん) に返信
> ■No4853 (倉田 有大 さん) に返信
>
> SHGetSpecialFolderLocation じゃないとだめなんですか?
> SHGetSpecialFolderPath とか、SHGetFolderPath とかではだめなのでしょうか?
>
> こちらなら、IMalloc はいらないですよね?ITEMIDLISTじゃないとだめという場合もあるので
> 一概には言えませんが...
>
> で、実装ですが、IMalloc が必要なのなら、その都度確保ではなく、最初に確保したら
> 以後ずっと使いまわしが基本です。もちろん STA でw
>
> ちなみに、COMオブジェクトを開放するのに IUnknown を引っ張る必要はありません。
> いらなくなった時点で
> System.Runtime.InteropServices.Marshal.ReleaseComObject(alloc);
> を呼び出すだけでOKです。
>
> キャストした場合は、キャストしたオブジェクトごとに呼び出す必要があるはずです。
> .NET では原則として IUnknown を必要とする処理はいらないはずです。
> #もちろん、メソッドとしてのAddRef/Releaseも含め

どうもありがとうございます<__>
SHGetSpecialFolderPath なんですが、使用してみたところ

[DllImport("coredll.dll", SetLastError = true)]
public static extern bool SHGetSpecialFolderPath(
int hwndOwner,
string lpszPath,
ShellSpecialFolder nFolder,
bool fCreate);

coredllがないぞ〜
みたいなこといわれます。XP s2なのになあ。
なんか、インストールしないといけないのかな?
shell32.dllにもないといわれるし、どこにあんねん;_;

>で、実装ですが、IMalloc が必要なのなら、その都度確保ではなく、最初に確保したら
以後ずっと使いまわしが基本です。もちろん STA でw

あら、そうだったんですか。
確保しまくっていたわたしはいったい^^;

WindowsAPI.SHGetSpecialFolderLocation(Handle, shellSpecialFolder, out idHandle);
Marshal.FreeCoTaskMem(idHandle);
とりあえず、今回はこれでいいのでしょうか?

引用返信 編集キー/
■4871 / inTopicNo.7)  Re[5]: SHFreeMallocの使い方
□投稿者/ Atata!! (3回)-(2007/06/27(Wed) 22:06:09)
> 返信ありがとうございます。
> FreeCoTaskMemを調べてみましたが、AllocCoTaskMemと一緒に使うのでしょうか?

私の調べた限りでは、IMalloc::Alloc や CoTaskMemAlloc により
メモリの割り当てを開放するのに使用しても問題なさそうです。


> SHGetSpecialFolderLocation じゃないとだめなんですか?
> SHGetSpecialFolderPath とか、SHGetFolderPath とかではだめなのでしょうか?
>
> こちらなら、IMalloc はいらないですよね?ITEMIDLISTじゃないとだめという場合もあるので
> 一概には言えませんが...

私もそう思います。さらに言うと Environment.GetFolderPath でも良いような気が・・・。
引用返信 編集キー/
■4873 / inTopicNo.8)  Re[6]: SHFreeMallocの使い方
□投稿者/ 渋木宏明(ひどり) (247回)-(2007/06/27(Wed) 22:09:30)
渋木宏明(ひどり) さんの Web サイト
> coredllがないぞ〜
> みたいなこといわれます。XP s2なのになあ。

あるはずないです。
coedll.dll は Windows CE で kernel32, user32, gdi32 の代わりを務めるものです。

> shell32.dllにもないといわれるし、どこにあんねん;_;

\Windows\system32 配下です。

引用返信 編集キー/
■4875 / inTopicNo.9)  Re[6]: SHFreeMallocの使い方
□投稿者/ とっちゃん (155回)-(2007/06/27(Wed) 22:15:16)
とっちゃん さんの Web サイト
No4870 (倉田 有大 さん) に返信
>
> [DllImport("coredll.dll", SetLastError = true)]
> public static extern bool SHGetSpecialFolderPath(
> int hwndOwner,
> string lpszPath,
> ShellSpecialFolder nFolder,
> bool fCreate);
>
> coredllがないぞ〜
> みたいなこといわれます。XP s2なのになあ。

XPには、coredll.dll はないと思います。
これがあるのは、CE 系OSですからw

> なんか、インストールしないといけないのかな?
> shell32.dllにもないといわれるし、どこにあんねん;_;
>
shell32.dll でいいはずなんですけどね?
もしかしたら、OS(IEのバージョン)によって違うのかな?

>
> WindowsAPI.SHGetSpecialFolderLocation(Handle, shellSpecialFolder, out idHandle);
> Marshal.FreeCoTaskMem(idHandle);
> とりあえず、今回はこれでいいのでしょうか?
>
Marshal.FreeCoTaskMem が最終的に CoTaskMemFree APIを呼び出していると書いてあるので
たぶん大丈夫だと思います。

実際、SHGetMalloc で持ってくる IMalloc インターフェースは、CoTaskMemAlloc/Free の
ラッパーですしw

引用返信 編集キー/
■4876 / inTopicNo.10)  Re[3]: SHFreeMallocの使い方
□投稿者/ 渋木宏明(ひどり) (248回)-(2007/06/27(Wed) 22:15:50)
渋木宏明(ひどり) さんの Web サイト
> 提示されている SHFreeMalloc の代わりに Marshal.FreeCoTaskMem を使用するべきです。

SHGetMalloc() の最新のヘルプを読むと「SHGetMalloc() = IMalloc の代わりに CoTaskMemAlloc(), CoTaskMemFree() を使え」とありますね。

# 完全に Obsolate 扱いになってるのでびつくり。

で、.NET では CoTaskMemXXX() のラッパとして Marshal.AllocCoTaskMem(), Marshal.FreeCoTaskMem() が用意されているので、それを使うべきですね。


引用返信 編集キー/
■4877 / inTopicNo.11)  Re[7]: SHFreeMallocの使い方
□投稿者/ 倉田 有大 (33回)-(2007/06/27(Wed) 22:17:13)
返信ありがとうございます。

>>coredllがないぞ〜
>>みたいなこといわれます。XP s2なのになあ。
>
> あるはずないです。
> coedll.dll は Windows CE で kernel32, user32, gdi32 の代わりを務めるものです。

CE用でしたか、うわはずかし^^;

>>shell32.dllにもないといわれるし、どこにあんねん;_;
>
> \Windows\system32 配下です。

これはどういうことでしょうか?

[DllImport("Shell32.lib", EntryPoint="SHGetSpecialFolderPathA",SetLastError = true)]
public static extern bool SHGetSpecialFolderPath(
IntPtr hwndOwner,
string lpszPath,
ShellSpecialFolder nFolder,
bool fCreate);

この宣言の仕方がまちがっているのかな。
引用返信 編集キー/
■4878 / inTopicNo.12)  Re[7]: SHFreeMallocの使い方
□投稿者/ 倉田 有大 (34回)-(2007/06/27(Wed) 22:23:40)
うわわ、みなさん返信ありがとうございます。

Environment.GetFolderPath
だと、マイネットワークがみつからなかったのですが、どこかにあるのかな?

今日は休憩します。みなさまありがとうございました<__>
引用返信 編集キー/
■4879 / inTopicNo.13)  Re[8]: SHFreeMallocの使い方
□投稿者/ 魔界の仮面弁士 (320回)-(2007/06/27(Wed) 22:24:01)
No4877 (倉田 有大 さん) に返信
> [DllImport("Shell32.lib", EntryPoint="SHGetSpecialFolderPathA",SetLastError = true)]

lib ファイル…?
引用返信 編集キー/
■4880 / inTopicNo.14)  Re[6]: SHFreeMallocの使い方
□投稿者/ 渋木宏明(ひどり) (249回)-(2007/06/27(Wed) 22:27:47)
渋木宏明(ひどり) さんの Web サイト
> coredllがないぞ〜
> みたいなこといわれます。XP s2なのになあ。

なんとなく原因が分かった。

DVD 版の MSDN Library の「キーワード」で SHGetMalloc() を検索してるでしょ?

Windows CE に同名の API がある場合、「キーワード検索結果」には Windows CE 版のヘルプトピックの方が上に表示されるので、そっちを見てるじゃないですか?
引用返信 編集キー/
■4881 / inTopicNo.15)  Re[9]: SHFreeMallocの使い方
□投稿者/ 倉田 有大 (35回)-(2007/06/27(Wed) 22:29:00)
No4879 (魔界の仮面弁士 さん) に返信
> ■No4877 (倉田 有大 さん) に返信
>>[DllImport("Shell32.lib", EntryPoint="SHGetSpecialFolderPathA",SetLastError = true)]
>
> lib ファイル…?

すいません、そこでした<__>

string path = new string(' ', 256);
WindowsAPI.SHGetSpecialFolderPath(Handle, path, TTFA.Win32.ShellSpecialFolder.CSIDL_NETWORK, false);

でもPathに何もはいってきませんでした。
うーん、次はどうしようかな。
引用返信 編集キー/
■4882 / inTopicNo.16)  Re[10]: SHFreeMallocの使い方
□投稿者/ 倉田 有大 (36回)-(2007/06/27(Wed) 22:31:44)
No4881 (倉田 有大 さん) に返信
> ■No4879 (魔界の仮面弁士 さん) に返信
>>■No4877 (倉田 有大 さん) に返信
> >>[DllImport("Shell32.lib", EntryPoint="SHGetSpecialFolderPathA",SetLastError = true)]
>>
>>lib ファイル…?
>
> すいません、そこでした<__>
>
> string path = new string(' ', 256);
> WindowsAPI.SHGetSpecialFolderPath(Handle, path, TTFA.Win32.ShellSpecialFolder.CSIDL_NETWORK, false);
>
> でもPathに何もはいってきませんでした。
> うーん、次はどうしようかな。

いったん寝ます。明日またがんばろー
みなさん、ありがとうございました〜
引用返信 編集キー/
■4883 / inTopicNo.17)  Re[10]: SHFreeMallocの使い方
□投稿者/ 魔界の仮面弁士 (321回)-(2007/06/27(Wed) 22:32:56)
2007/06/27(Wed) 23:03:00 編集(投稿者)

No4881 (倉田 有大 さん) に返信
> でもPathに何もはいってきませんでした。
> うーん、次はどうしようかな。

string ではなく、StringBuilder 型で受け取る必要があるのでは。

http://msdn.microsoft.com/library/ja/cpguide/html/cpconDefaultMarshalingForStrings.asp
http://msdn2.microsoft.com/ja-jp/library/s9ts558h%28VS.80%29.aspx
》 String クラスと StringBuilder クラスのマーシャリングの動作は似ています。
》 主な違いは、文字列は変更不可であるのに対して、StringBuilder バッファの内容は
》 呼び出し先によって変更でき、呼び出し元へとコピーできることです。


試してはいませんが、たぶん、こんな感じかな、と。

[DllImport("shell32.dll")]
static extern bool SHGetSpecialFolderPath(
IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder, bool fCreate);

--------------
<追記>

……って、指定しているのは CSIDL_NETWORK(マイ ネットワーク) でしたか。

マイ ネットワーク フォルダは、物理ディレクトリではなく、仮想ディレクトリなので
パスは得られないと思いますけれども。

無理に対応するとすれば、
 if(nFolder==ShellSpecialFolder.CSIDL_NETWORK)
  return "::{208D2C60-3AEA-1069-A2D7-08002B30309D}";
みたいにするとか、かな。
引用返信 編集キー/
■4888 / inTopicNo.18)  Re[4]: SHFreeMallocの使い方
□投稿者/ Atata!! (4回)-(2007/06/28(Thu) 00:43:20)
> SHGetMalloc() の最新のヘルプを読むと「SHGetMalloc() = IMalloc の代わりに CoTaskMemAlloc(), CoTaskMemFree() を使え」とありますね。
>
> # 完全に Obsolate 扱いになってるのでびつくり。

それは私も驚きました。MSDNに書いてあるのは知りませんでした。

私は、CoTaskMemAlloc で確保したメモリを Marshal.FreeCoTaskMem で開放し
Marshal.AllocCoTaskMem で確保したメモリを CoTaskMemFree で開放するという
簡単なアプリを作って1晩動作させた後、タスクマネージャでプロセスの仮想メモリサイズが
開始時とそれほど変化が無いう方法で確認しました。
引用返信 編集キー/
■4889 / inTopicNo.19)  Re[5]: SHFreeMallocの使い方
□投稿者/ 渋木宏明(ひどり) (250回)-(2007/06/28(Thu) 05:24:19)
渋木宏明(ひどり) さんの Web サイト
2007/06/28(Thu) 05:31:35 編集(投稿者)

> 私は、CoTaskMemAlloc で確保したメモリを Marshal.FreeCoTaskMem で開放し
> Marshal.AllocCoTaskMem で確保したメモリを CoTaskMemFree で開放するという
> 簡単なアプリを作って1晩動作させた後、タスクマネージャでプロセスの仮想メモリサイズが
> 開始時とそれほど変化が無いう方法で確認しました。

Marshal.AllocCoTaskMem(), Marshal.FreeCoTaskMem() は CoTaskMemXXX() のラッパであることがヘルプに明記されているので特に心配しないで混在使用してきました。

が、SHGetMalloc() と CoTaskMemXXX() については、同一のヒープを使っていることが(かなり強く)想像されますが、ドキュメント的にはイマイチ歯切れが悪かったりするので一応混在利用は避けてました。

# 混在使用→ 例) CoTaskMemAlloc() で確保したメモリを SHGetMalloc() で取得した IMalloc の IMalloc::Free() で解放。

引用返信 編集キー/
■4900 / inTopicNo.20)  Re[6]: SHFreeMallocの使い方
 
□投稿者/ 倉田 有大 (37回)-(2007/06/28(Thu) 10:56:05)
>……って、指定しているのは CSIDL_NETWORK(マイ ネットワーク) でしたか。

はいT^T
今回はSHGetSpecialFolderLocationで動いているので、これでいこうとおもいます。
みなさま、ありがとうございました。
それにしても、COMやらCOM+はいまだにわからんT~T
C#使うようになってから、アンマネージに触れることすくなくなったから、ますます触れることがありません。
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -