コンパイラはVisual C++ 2008 Express Editionです。
以下のようなコードを書くと
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <commctrl.h>
#pragma comment ( lib, "comctl32.lib")
HRESULT InitCOM_Ole32(){ //初期化
HMODULE hDLL( LoadLibrary(_T("Ole32.dll")) );
if (!hDLL) return E_FAIL;
typedef HRESULT (*Func)( LPVOID );
Func func = (Func)GetProcAddress(hDLL,"CoInitialize");
HRESULT hr( func( 0 ) );
FreeLibrary( hDLL );
return hr;
}
void UnInitCOM_Ole32(){ //後始末
HMODULE hDLL( LoadLibrary(_T("Ole32.dll")) );
if (!hDLL) return;
void (*func)() = (void (*)())GetProcAddress(hDLL,"CoUninitialize");
func();
FreeLibrary( hDLL );
}
int main(){
InitCOM_Ole32();
InitCommonControls();
UnInitCOM_Ole32();
getchar();
return 0;
}
最適化オプションが無効なら問題ないのですが、最適化オプションを付けると
getchar();
直後に落ちてしまいます。
また、別のプロジェクトでも、最適化オプションなしなら正常に動くのですが、最適化オプションを付けると、そちらは初期化関数サイドを抜ける瞬間には落ちてしまいます。
アセンブリ出力を見ても、関数名とかはそのまま書かれている分に感じるので、どこがまずいのかよく分かりません。
これらはどのように対処すればいいのでしょうか?
あるいは、書き方自体が間違っている(未定義動作になる)部分があるのでしょうか?
No.2ベストアンサー
- 回答日時:
WindowsAPIの呼び出し規約はstdcallで、VC++のデフォルトの呼び出し規約はcdeclです。
ですので、stdcallを指定しなければ、stdcallの関数をcdeclで呼んでしまいおかしなことになります。
ですので、
typedef HRESULT (__stdcall * Func)( LPVOID );
みたいにする必要があります。
WindowsAPIならこっちの方が良いかも知れません。
typedef HRESULT (WINAPI * Func)( LPVOID );
なるほど!
そういえば数回無意識に触れていたようですが、呼び出し規約という概念自体、あまりよく知らなかったです。
これを機に調べてみて納得しました。
また、jgkさんのおっしゃる通りWindowsAPI用に呼び出し規約を指定することで、どちらのプロジェクトも問題なく動作するようになりました。
ただ、質問文のコードのLoadLibrary、FreeLibraryの使い方が、この場合は問題ないのかあるのかはやはり気になるので、最大で数日程度締め切りを待たせてください。
No.1
- 回答日時:
CoInitializeとCoUninitializeを別の
インスタンスで実行して大丈夫なんですか?
普通に考えると気持ち悪いですね。
何かMSのドキュメントで保証されているので
しょうか?
同じインスタンスで実行するようにhDLLを
大域変数として、後処理でのみFreeLibraryを
実行するように修正してみたらどうなりますか?
ありがとうございます。
分かりやすくグローバルな位置(とかただの名前空間内)に持ってきて、初期化サイドから
FreeLibrary
を
後始末サイドから
LoadLibrary
を消して「最適化オプション付き」でやってみると、今度は「初期化関数を抜けるときに」確実に落ちるようになりました。
最適化オプションなしならやはりhDLLが同じ変数であってもなんら問題はありません。
LoadLibraryについて
http://msdn.microsoft.com/ja-jp/library/cc429241 …
HMODULEというのは文字通りモジュールハンドルなのでDLLを必要に応じてロードしたり解放したり、というのは意味的にも問題ないと思っていましたが、逆に(COMの初期化、後始末が関係するという点で)上記質問文のコードの場合は問題がある、という記述はあるのでしょうか?
いちおう質問文でのコードではアドレスが一致するか調べてみましたが
TCHAR c[100];
_stprintf_s(c,100,_T("%p"),hDLL);
_tprintf(c);
別のインスタンスで実行して、同じアドレスが得られました。
やはり最適化でどっかが浸食されてるんじゃないかな…
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# Cのオブジェクトファイルの逆アセンブル 5 2023/05/13 01:51
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- その他(プログラミング・Web制作) python flask から fastapiへの移行時のエラー対処 1 2023/02/05 12:26
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- Ruby 教えてください 2 2023/01/04 17:50
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・ハマっている「お菓子」を教えて!
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# Controls.Addで動的に配置し...
-
DLLの関数呼び出しで引数がある...
-
(void)0 はどんな意味ですか
-
自作DirectShow Filterのinter...
-
静的でないメンバ関数の呼び出...
-
C言語 ① 5秒間 1秒間隔で点滅を...
-
コールバックって・・・
-
既定のコンストラクタがありま...
-
C#でラジオボタンを設定に記録...
-
【gcc・cygwin】multiple defin...
-
typedef unsigned int UINT;が...
-
C++にてtemplateで受け取った任...
-
VC++でGetKeyboardStateがうま...
-
戻り値を返す関数の前に(void)...
-
プログラムを教えてください。...
-
プログラミング初心者です。 Py...
-
信頼区間の1.96や1.65ってどこ...
-
マイナスからプラスへ転じた時...
-
入力した文字列から母音だけを...
-
「Aに対するBの割合」と「Aに対...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【gcc・cygwin】multiple defin...
-
静的でないメンバ関数の呼び出...
-
C++にてtemplateで受け取った任...
-
戻り値を返す関数の前に(void)...
-
多重定義が起きている?--lnk20...
-
既定のコンストラクタがありま...
-
C# Controls.Addで動的に配置し...
-
(void)0 はどんな意味ですか
-
int main()、void main()、void...
-
const_castのつかいどころを教...
-
C# KeyDownイベントでショート...
-
VC++でGetKeyboardStateがうま...
-
void*型の配列について
-
C#でラジオボタンを設定に記録...
-
Notepad++の関数リスト表示の変...
-
ArduinoでMouse関数を使用して...
-
_beginthreadにて発生するコン...
-
コールバックって・・・
-
ウインドウの移動禁止
-
構造体を宣言と共に初期化する方法
おすすめ情報