Win7のみ対応APIをVistaで無効化したい – プログラミング – Home

Win7のみ対応APIをVistaで無...
 
通知
すべてクリア

[解決済] Win7のみ対応APIをVistaで無効化したい


d
 d
(@d)
ゲスト
結合: 20年前
投稿: 6
Topic starter  

VS2010 配布環境:Win7/Vista

教えてください。
Win7でディスプレイ制御をしたく、
GetDisplayConfigBufferSizes/SetDisplayConfig/QueryDisplayConfig
を使用します。Win7上での動作は問題ありません。

同じモジュールをVistaでも配布する必要がありますが、
Win7のみ対応APIのようでエントリポイント不明で例外となります。
(MSDNにはVista以上とあるが、ヘッダにはWINVER>0601)

ためしに、user32.libをプロジェクト設定から外して
LoadLibrary→GetProcAddres→見つからなければVista
と判定してVista上の例外回避はできたのですが
今度はWin7上でアクセスバイオレーションが出るようになってしまいました。

どうすればいいか手詰まりの状況です。
正しい方法?を教えて頂きたく宜しくお願いします。


引用未解決
トピックタグ
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

GetProcAddress で指定している関数名が間違っているとか
正しくキャストできていないのでアセンブラレベルで正しく呼べていないとか
単純にその辺のような気のせいがする。
いかんせんソースコードの提示無しでは妄想に憶測を重ねるだけかと。

> ためしに、user32.libをプロジェクト設定から外して
はずさなくても良いのでは・・・


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

んでは、自分は別のアプローチを・・。
targetver.h ってのがあると思うのですが、無ければ
WINVERと、_WIN32_WINNTの定義をしている部分を検索してください。
この定義は全てのインクルードに先立って行われるので、プリコンパイルの
近傍にあります(多分)。

さて、この二つの定義は「最低限必要なプラットホームのバージョン」を意味し、
コンパイル時に決定される条件となります。
例えば、#defien _WIN32_WINNT 0601 //(Windows7)が指定された場合、
コンパイラはこのアプリが動作するときの、最低限必要なプラットホームの
バージョンはWindows7だとして処理します。
当然ですが、この場合、Vista(0600)はそのプラットホームに満たないので、
対象外(Vistaでは動作しなくて良い)という処理になるわけです。

つまり、疑惑の関数がWindows7のみ対応であれば、
#define WINVER 0600 // Vista以上で動いてね
#defien _WIN32_WINNT 0600 // Vista以上で動いてね

とすれば、当該関数のところで何らかの警告かエラーが出ると思われます。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

ごめん orz.
ヘッダーを確認済みなのですね(vv;)
そうなると、MSさんのドキュメントの間違いである可能性が高いですね。
http://msdn.microsoft.com/en-us/library/windows/hardware/ff566778(v=vs.85).aspx
には、そう書いてあるし。

んで、アクセスバイオレーションはどこで発生するのでしょう。


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

> ためしに、user32.libをプロジェクト設定から外して
> LoadLibrary→GetProcAddres→見つからなければVista

user32.libを外さないで、
GetProcAddressで見つかったら、
その関数ポインタを呼ぶようにすれば良いと思います。

ちなみに、GUIならはuser32.dllはloadされているはずなので
GetModuleHandleでも良いです。


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

追加です。
ヘッダの関数宣言にWINAPIなどがついていれば
関数ポインタの関数型にもつけてください。 (WINAPI は __stdcallの意)


返信引用
d
 d
(@d)
ゲスト
結合: 20年前
投稿: 6
Topic starter  

たくさんのコメントありがとうございます。
なかなか手がつけられず遅くなって申し訳ありません。
結果としてロマさんの御指摘(WINAPI宣言漏れ)で解決しました。

typedef LONG (*TYPE_GETDISPLAYCONFIGBUFFERSIZES)(UINT32, UINT32*, UINT32*);

typedef LONG (WINAPI *TYPE_GETDISPLAYCONFIGBUFFERSIZES)(UINT32, UINT32*,
UINT32*);

やはり最初にソース提示すべきでしたね...。
お恥ずかしいですが、コピペでなんとなく動くを繰り返していたので、
きちんと勉強して理解したいと思います。

ありがとうございましたm(_ _)m


返信引用
Atata!!
 Atata!!
(@Atata!!)
ゲスト
結合: 18年前
投稿: 25
 

解決した後で何ですが、VS2010を使用されているなら
decltypeの使用を検討しても良いのではないでしょうか?

http://dev.activebasic.com/egtra/2009/06/04/202/


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

マイナーな機能ですが遅延ロードというのがあります。
LoadLibrary → GetProcAddress を自動でやってくれる機能です。

プロジェクトのプロパティで、[DLLの遅延読み込み]に user32.dll を書いてやること
で、普通に GetDisplayConfigBufferSizes(...) と書いたのが、内部的に動的呼び出し
に変換されます。
ただし、VerifyVersionInfo API 等を使用して、非対応バージョン(Vista)では、この
部分のコードを呼び出さないようにする必要があります。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました