アプリ版:「スタンプのみでお礼する」機能のリリースについて

自作のライブラリの場合は任意で
ユーザーが任意のプラグイン読み込めるアプリなら
プラグインに関してはdllでしょうが

公共的なライブラリについて
動的ロード推奨か、静的リンクでもいいという線引はどのあたりなのでしょうか

現状では

ole32.dll
msimg32.dll
comctl32.dll
comdlg32.dll
dsound.dll
kernel32.dll
shlwapi.dll
shell32.dll
uxtheme.dll

を動的にロードし

winmm.lib
user32.lib
gdi32.lib

を静的にリンクしています。
kernel32とかはさすがに静的リンクでもOKでしょうか?
あるいはwinmmとかは動的な方がいいでしょうか?

なお、対象はWindowsでXP以降とする場合、です。
(Windows以外の場合も教えていただけるとより良いですが)

あと、dsound.dll
とかについてですが

DirectSoundCreate8
だけGetProcAddressすれば

あとの

struct IDirectSound8;
struct IDirectSoundBuffer8;

のメンバなどについてはGetProcAddressしなくても使えるようだし
リンクエラーにならないのですが、これはどんな感じの仕組みになっているのでしょうか?

あるいは、それを気にしなくてもこれは「そうやっておけば問題ない」
としておいてもいいようなものなのでしょうか?

A 回答 (4件)

教えてgooでは質問者が自ら書き加えたくても


出来ないようになっているため

別IDを作ることで、経過報告のスペースを確保させていただきます。
質問者です。
(自身の別IDにつけるのは「お礼」ではなく「補足」のみで、ベストアンサーに選ぶこともありません。自作自演は禁止されているようですが、この利用法なら自作自演には到底ならないはずです。)

この回答への補足

標準ライブラリというのは、おそらくは

C ランタイム ライブラリ
http://msdn.microsoft.com/ja-jp/library/abx4dbyh …

に書いてある事が正確っぽいですね。

C ランタイム ライブラリに関してならば

プロパティ→構成プロパティ→C/C++→ランタイムライブラリ
のところをいじれば(DLLとついてない方にすると)
実行ファイルが大きくなったので
おそらくこうすると全部埋め込み式になるのではないかと思いますが


自作dllのサイズを縮小するときにやるように

構成プロパティ→リンカ→入力→すべての既定のライブラリの無視

を「はい」にしたら
いいえのときにビルド出来ていたコードで
2000個以上のリンクエラーが出たので

その時に含まれていた

memmoveに目をつけて

「すべての既定のライブラリの無視」は「いいえ」に戻しておき

実験ソースの一部を

static int i=0;
if (!i){
++i;

HMODULE hDLL = ::LoadLibrary( _T("msvcrt.dll") );

typedef void* (__cdecl*F1)( void*, const void*, szt );


struct DATA { F1 f1; Float* data; } data;

data.f1 = (F1)GetProcAddress(hDLL,"memmove");

float* const fdata = (float*)malloc(10000*sizeof(float));
for ( int i = 0; i<10000; ++i ) fdata[i]=(float)i;
data.data = fdata;

struct FUNCTOR { void operator()( const DATA* data ){
for ( int i = 0; i<10000; ++i ) data->f1( data->data + (i%999), data->data, sizeof(float)*(i%9000) );
}};

Debug::Performance a(false);
a.Check( FUNCTOR(), &data, 10 );
free( fdata );
FreeLibrary( hDLL );

}

と書き変えて
実行速度重視 (/O2)
でやってみると

(リリースビルド、デバッグビルドともに大して変わりがなく)

Averageが、例えば 0.022401324730242


data->f1(... 

memmove(...
にかえ


/MD
にすると
Average: 0.022600945383129


/MT
にすると
Average: 0.021842370953631

となりました。

なお
出力されたアセンブリコードを比較してみると


/MD のときだけ明白な形


movedi, DWORD PTR __imp__memmove

push命令3つ含む色々な処理

calledi


となっていましたが

その他の2つでも

push命令3つ 



call何々

は確実に行われていたので

少なくとも私の環境に於いていてば
このコードで、どのパターンであっても
memmoveはインライン展開はされておらず

関数のアドレス指定の方法が変わっただけでした。


これだけで判断しきれたとは言えませんが
おそらく大よその傾向はつかんだと思います。

動的リンクと静的リンクの差は、コンパイラが普通じゃないようなよほど気の利いた(?)行動をした場合でなければ、10000回のループでも

動的
0.022600945383129
0.022401324730242 //関数ポインタの位置はこっちのが近い場合

静的
0.021842370953631

この程度の差に収まるであろう
ということで
まぁ「本当にとんでもないほどよほど」の場合でもなければ
普通の動的リンクで十分と考えてよさそうです。



と、いうわけで
解決とさせていただきます。

補足日時:2012/01/26 00:01
    • good
    • 0

#1です。

#1に書いた補足の所の回答をします。

・実行速度の件
アセンブラコードを見ると判るのですが、動的リンクの場合は、DLLに対応するジャンプテーブルが、コード領域の最後に作られるらしく、一度そちらにジャンプしてからDLLのコードに飛んでいきます。
それに対して、(実証したことがないので推測ですが)静的リンクの場合は自EXE内に既にコードが展開されるので、直接ジャンプしているものと推測しています。(どこにあるか判るのでジャンプテーブルは必要ないはず)
なので、若干静的リンクが早いとは思いますが、正直ループで1万回まわしてどれだけ差が出るの?って感じ程度だと思います。
キャッシュミスを考えても、そもそもコード量>1次命令キャッシュがほとんどですから、どっちにしろコード量が大きければ、静的リンクも動的リンクも同じくらいヒットしたりミスしたりするとおもいますが。
動的DLL部分だから違うキャッシュ空間を使う、というわけでもありませんからね。DLLのコードの位置が、ちょっと離れているか、自EXE内にあるか、というだけで、そもそもキャッシュは関数レベルでリードしているわけではありませんから、どっちもどっちかと思いますよ。
ただ、前述のジャンプテーブルの分だけ、動的リンクの方がキャッシュを使いつぶしやすいでしょうけど。

・アップグレード権うんぬんの話
これについては、たしかにインストール時に必要なパッチをインストールさせる手もありますね。
ただし、そのEXEをCDやDVDに入れないといけないですが。
また、そこに至るまでの前提パッチ全て入れる必要もあります。
(このあたりのパッチの依存関係を調べるのは大変じゃないですかね・・・?)

・TrackMouseEventの件
さすがに、プラットフォームSDKのヘッダに記載されている名称そのままはぶつかりますので使えません。
ですが、LoadLibraryとGetProcAddress()を使っているなら、その取得したアドレスをポインタに格納すれば名称変更で同じことができると思いますが。
  typedef BOOL (*LOADADDR_TRACKMOUSEEVENT)( LPTRACKMOUSEEVENT lpEventTrack );

  LOADADDR_TRACKMOUSEEVENT pTrackMouseEvent = (LOADADDR_TRACKMOUSEEVENT )GetProcAddress(~);

  LPTRACKMOUSEEVENT event;
  BOOL brc = pTrackEvent( &event );

こんな感じでいけると思います。これで、”TrackMouseEvent”を、”pTrackMouseEvent”と置換するだけで済むかと。


・#2さんのお礼の所にあったLIBの話
自分の所ではないのですが、思ったことが1つあったので、書いておきます。

たしかに、libの中にコードが入っているコンパイラもあります。
私も使ったことはあります。自分の担当分をlib化してコードを1つにしておいて、後で他人の作ったLIBと合わせて1本にする、という用法です。

ただし、Windowsの開発環境の場合は、LIBにコードは含まれていないはずなのですが。
主さんがLIB=静的リンク、と言っているのは、上記の通り、そういう環境で開発したことがあるからではないかな、と推測しますが、どうでしょうか?

私が認識している感じでは、winmm.lib等、プラットフォームSDKに入っているlibは、あくまでこれに対応するDLLに格納している関数名とその引数の数やオフセットアドレス位しか格納していないと思いました。

なので、まとめてしまうと、Windowsの場合に限っていえば、静的リンクはDLLのコードごとEXEに組み込むことを指し、動的リンクはEXE実行時にDLLをロードして使う(LIBを使ってコンパイル・リンクして、自動でロードさせる)、または、EXE側でLoadLibrary+GetProcAddressで使うことを指す、ということになります。

なお、#pragma comment( lib, "winmm.lib" )は、主さんの書いている通り、追加の依存関係に書くのと同じです。
(なので、私も1箇所でしか使っていない場合とか、他人に流用させることを意識したソースコードの場合は#pragmaを使います)

・必要DLLが無い環境でのEXE実行の件
d3dx9.dllの話を出していますが、主さんの書いており通り、d3dx9.libに対応するDLLがなければEXEは起動できませんので、通常はこのDLLが無い環境にインストールされるかもしれないと想定される場合は、インストーラーでインストールして導入させる必要があります。

何でもいいのですが、アプリをインストールしていて、インストーラーからインストーラーを起動する光景をみたことはありませんか?
もしくは、ゲームのインストーラーに必ずと言って良い位、DirectXのインストーラーもついて来ます。これを入れないと動かないぞと言わんばかりです。
つまり、導入しないなら使えない、使いたいなら前提となるDLLをインストールしてください、というのが動的リンクを使ったEXEを使う場合の前提です。ただし、これをやると以降のバージョンUPの際は、EXE入れ替えのみで済むという手抜きアップグレードができたりします。(普通やらないでしょうけど)
これがいやな場合は、静的リンクにするしかありません。無いものは自前で用意する、という感じですね。

・静的リンクのアプリの作り方
すいませんが、静的リンクはMFCでしかやったことがないので、他のDLLの静的リンクの方法はわかりません。
MFCのDLLの場合は、プロジェクト設定時に指定できるので、スイッチポンで指定できるのですが・・・他のは設定がありませんね。もしかしたら、自分でリンカの所にオプションを追加するのかもしれません。

この回答への補足

ま、でも

・自作の静的リンクライブラリでは、やはりinline展開する方法はないか?
・「標準ライブラリ」は、通常静的であるのか?
・Windows関連のlibについては、静的リンクは出来るのか?

この辺は分からなくても、十分な情報が得られたので
しばらく待って謎のままでも締め切りにしようと思います。




とりあえず、gdi32.dllの関数定義を静的リンク出来る方法は分からないので、ひとまずおいといて
それ以外の動的な方法の細かいところのパフォーマンス比較をしてみました。
劇的な信頼性はないですが、ある程度の指標にはなり得ると思います。

実行速度重視に設定し、リリースビルドでもデバッグビルドでもほぼ変わりませんでした。

↓コードはこんな感じです

//Debug_Performance.hの内容

#pragma once


#if DEBUG_

namespace Debug { struct Performance; }

struct Debug::Performance {

LARGE_INTEGER FQ, Be, Af;
const bool b;

Performance( bool output_by_destructor = true ) : b(output_by_destructor) {

ZeroMemory( &FQ, sizeof FQ );
ZeroMemory( &Be, sizeof Be );
ZeroMemory( &Af, sizeof Af );
QueryPerformanceFrequency(&FQ);
if (b) QueryPerformanceCounter(&Be);

}

template < class T, class F > void Check( F f, T t, const int count ){

FILE* fp;
if ( fopen_s( &fp, "sec.txt", "w" ) ) return;

char c[64];
double total = 0;
double time;
for ( int i = count; i--; ){
if (!b) QueryPerformanceCounter(&Be);
f(t);
QueryPerformanceCounter(&Af);
time = double(Af.QuadPart - Be.QuadPart) / FQ.QuadPart;
total += time;
sprintf_s(c,64,"%.15f\r\n",time);
fwrite(c,1,strlen(c),fp);
}

if ( 1 < count ){
sprintf_s( c, 64, "\r\nAverage: %.15f\r\n", total/count);
fwrite(c,1,strlen(c),fp);
}

fclose(fp);

}

struct FUNCTOR { void operator()(int) const {} };

~Performance(){ if (b) Check( FUNCTOR(), 0 , 1 ); }


};

#endif




////とあるソースととある関数//////


#include "Debug_Performance.h"

void ほげ::Draw( HDC hdc ) const {

/* 描画関数の中に↓を付けたしました。単位は秒になります。(実験用に作ったので、チェックとかもしてない
間に合わせコードですがw) */

static int i=0;
if (!i){
++i;

HMODULE hDLL = ::LoadLibrary( _T("Gdi32.dll") );

typedef BOOL (WINAPI*F1)( HDC, int, int, LPPOINT );
typedef BOOL (WINAPI*F2)( HDC, int, int );

struct DATA { HDC hdc; F1 f1; F2 f2; } data;

data.hdc = hdc;
data.f1 = (F1)GetProcAddress(hDLL,"MoveToEx");
data.f2 = (F2)GetProcAddress(hDLL,"LineTo");

struct FUNCTOR { void operator()( const DATA* data ){
data->f1( data->hdc, 0, 0, NULL );
for ( int i = 0; i<10000; ++i ) data->f2( data->hdc, i%9, i%100 );
}};

Debug::Performance a(false); //trueではコンストラクタ~デストラクタまでを1回計測
a.Check( FUNCTOR(), &data, 10 ); //10回計測

FreeLibrary( hDLL );

}




これだと

0.000636244332551
0.005826080973320
0.010637035838782
0.006537797726185
0.005375078262058
0.005624915814176
0.000888535690688
0.006076577886127
0.006023611218701
0.005941781686451

Average: 0.005356765942904




data->f1( ...
for ( int i = 0; i<10000; ++i ) data->f2( ...



MoveToEx( ...
for ( int i = 0; i<10000; ++i ) LineTo( ...


に変えて
「DLLの遅延読み込み」にしてみると


0.005385412043471
0.005400828415848
0.005378640267936
0.006128306942198
0.005504823767971
0.0053886003964370.005391615593174
0.005413133444214
0.005401562051446
0.005467530928892

Average: 0.005486045385159


遅延読み込みではなくすと


0.005448111002256
0.005958235173498
0.005442285206534
0.005683783463580
0.005765973434189
0.006496710487344
0.005958681734296
0.010561534710989
0.001154714178305
0.005799237201249

Average: 0.005826926659224


でした。
全く誤差の範囲と思いますが、もしかすると
関数ポインタに相当する物のアドレスの違いで若干の違いが出ていたかどうか
って言うぐらいですかね。

ただ少なくとも、これらに関しては全く誤差の範囲とは思います。

補足日時:2012/01/25 01:31
    • good
    • 0
この回答へのお礼

再度ありがとうございます♪


>キャッシュミスを考えても、そもそもコード量>1次命令キャッシュがほとんどですから、どっちにしろコード量が大きければ、静的リンクも動的リンクも同じくらいヒットしたりミスしたりするとおもいますが。

確かに、1次命令キャッシュを上回る確率は高いはずですね

とはいえ、2次3次キャッシュなら静的リンクは十分望みがあるはず、と思います。
といっても、実験出来ないことにはあれですし、しかもDLLとの位置関係はつねに変化し得るとも思いますし、加えて

>若干静的リンクが早いとは思いますが、正直ループで1万回まわしてどれだけ差が出るの?って感じ程度だと思います。


そんな気もしますね。
逆に考えれば

>このあたりのパッチの依存関係を調べるのは大変じゃないですかね・・・?

その通りだと思いますw
ので、動的リンクで、想定されるいくらかの環境でのベンチマークが許容範囲だと感じたら、それでOKとするほうがかなり現実的な気もします。
(あくまで、実験はしてみたいものですが)



>こんな感じでいけると思います。これで、”TrackMouseEvent”を、”pTrackMouseEvent”と置換するだけで済むかと。

出来れば名前空間で包まないような最上級のグローバルは、最小限にしたいと思っていましたが
この場合は、やるとしても元々が元々なので問題ない、という考え方もありますね。

あ、でもLoadLibraryの時のHANDLEまでグローバルになるのがちょっとあれかもしれません。


現状では、例えばKernel32に関しては
Windows 98ではTryEnterCriticalSectionが使えないとの事で
それについては明示的にロードし、EnterCriticalSectionなどに関してはリンクという事にしておいて
(まぁ、98は公式のサポートが終了したこともありますし
XP以降限定ならぶっちゃけ必要ないかもしれませんが)

namespace MyLoadDLL{

namespace Kernel32{
typedef BOOL (WINAPI*F1)(LPCRITICAL_SECTION);
extern HMODULE hDLL;
extern F1 TryEnter; //TryEnterCriticalSection
BOOL WINAPI DefaultTryEnter(LPCRITICAL_SECTION);
HRESULT Load();
Void Free();
}


}

こんな感じの宣言になっています。cppでは

using namespace MyLoadDLL;

HMODULE Kernel32::hDLL;
Kernel32::F1 Kernel32::TryEnter;

HRESULT Kernel32::Load(){
hDLL = ::LoadLibrary( _T("kernel32.dll") );
if (!hDLL) return E_FAIL;
if ( !(TryEnter = (F1)GetProcAddress(hDLL,"TryEnterCriticalSection")) ) TryEnter = DefaultTryEnter;
return True;
}

Void Kernel32::Free(){ if (hDLL) FreeLibrary(hDLL); }

BOOL WINAPI Kernel32::DefaultTryEnter(LPCRITICAL_SECTION cs){
EnterCriticalSection(cs);
return TRUE;
}

みたいな感じですかね。
この辺はある程度任意でしょうね。

こうやっておく場合は、状況次第で

using 名前空間::名前空間::関数ポインタ名;

using namespace 名前空間::名前空間;

を別の「ソース」ファイルとか、そのソースの関数のスコープ内で使う事も十分関あげられます。また、関数ポインタ名自体は短くても、元の関数(あるいは意味)が簡単に思い出せる名前なら問題なさそうです。



>主さんがLIB=静的リンク、と言っているのは、上記の通り、そういう環境で開発したことがあるからではないかな、と推測しますが、どうでしょうか?


いえいえ、単なる知識不足でした(苦笑)
手持ちの環境では「libやdllを作る」という直接的な新規プロジェクトの選択肢もなかったので
長い間方法が分からなかったため、ライブラリをいじくり倒すことはほとんど出来なかったことが主要な原因です

このことに関しては
プロパティ→構成プロパティ→構成の種類で変更すればOKですね。


ただ、WindowsのSDK的なlibは動的リンク(か、変更できるとしても動的なのがデフォルト)だけども

「標準ライブラリ」ってのは、静的である(あるいはリンカなどの設定によって静的にになり得る)ってことであってる感じでしょうか?

・inline関数と、静的ライブラリとか標準ライブラリ関数とかの話
http://math314159.blog99.fc2.com/blog-entry-21.h …


もし本当に静的リンクだけでなくinline展開までしてくれるなら、話がまた少し変わってくる可能性がありますね。(多くの個所で大きめの関数をinline展開されるのは困りますが)


自作の静的リンクライブラリでは、やはりinline展開する方法はないでしょうか?




>通常はこのDLLが無い環境にインストールされるかもしれないと想定される場合は、インストーラーでインストールして導入させる必要があります。


結構その辺て詳しく知らないと戦慄の問題があるらしいですよねw

・DirectX 9のインストールがDirectX 10を破壊する
http://radeonbros.seesaa.net/article/112758341.h …


こういう事がなければいいのですが、あるとなるとこれもこれで、後々骨が折れるようなことが起きないとも限らないですねw


対処法としては、DirectX 9やDirectX 10に関しては
自アプリのインストーラ内で単純なフルのDirectXインストーラを用意して…っていうのは避ける、というあたりでしょうか。

お礼日時:2012/01/25 01:00

動的リンク/静的リンクの意味を取り違えていませんか?



静的リンクはリンク時にスタティックライブラリ(*.lib、実行コードが含まれている)を使用すること。
実行時には実行モジュール(*.exe)だけで実行できる。

動的リンクには二つの使用方法があり、
一つはリンク時にダイナミックライブラリへの参照が含まれるライブラリ(*.lib、実行コードが含まれていない)を使用する。DLLの一般的な使い方。
もう一方は、リンク時にライブラリを使用せず、プログラムでLoadLibrary, GetProcAddressを使用してアドレス解決を行った上で関数呼び出しを行う。通常こちらを動的ロードという。
どちらも、実行時には使用したライブラリに対応するDLLモジュールが必要。

静的リンクはリンク時にすべてのコードを実行モジュールに含めるため、コードが大きくなる。
動的リンクはリンクにDLLへの呼び出しだけを実行モジュールに含めるためコードが小さくなる。

何が一般的かといえば *.lib を使用した動的リンク。
動的ロードが必要なパターンはかなり少なくて、関数インターフェースが同じ複数のライブラリを使いまわしたいときなど。
例えば、国際対応(文字列リソースを置き換える)処理。

> winmm.lib
> user32.lib
> gdi32.lib
> を静的にリンクしています。
これらのライブラリを使用したからと言って静的リンクではないですよね。
実際の処理はこれらのライブラリに対応するdll(winmm.dll, user32.dll, gdi32.dll)で実行されるわけですから。

この回答への補足

調べまくってたら書き忘れてましたw
ご指摘ありがとうございます♪

補足日時:2012/01/24 21:17
    • good
    • 0
この回答へのお礼

むむ?そうなると質問の言葉が違うという事になりますね。

同じlibでも

>(*.lib、実行コードが含まれている)
>(*.lib、実行コードが含まれていない)

の違いがあるのですか。その場合同じ表記方法でも変わるということでしょうか?

例えば、普通に自分で
埋め込み式のtest.libを作ったとして、探せる位置に持っていっておいて

#pragma comment(lib, "test.lib")

の一行を書いて普通に関数を使うと、これは静的リンクになるということがいくつかのサイトに書かれていましたが(追加の依存ファイルに書いても同義(?))

自作でないuser32.libに関しては

#pragma comment(lib, "user32.lib")

だと参照だけが含まれているということで
動的リンクという扱いになる、ということでしょうか?

とりあえず
#pragma comment(lib, "d3dx9.lib")
とかやると、入ってないやつでは起動出来なかった
ようなきがするのですが

これは実行ファイルに埋め込まれているわけではないのでdllを参照しようとしたときに出来ないのでそうなっているだけということですか。


仮に

#pragma comment(lib, "test.lib")

にプラス
「DLLの遅延読み込み」にtest.dllと書いて普通に関数を使うと
使っている場所で遅延読み込みされる、ということですが



#pragma comment(lib, "user32.lib")

の場合は動的リンクであることに変わりなく
しかもDLLの遅延読み込みをしてしまうと
無駄なコードを作成してしまうことになる


では、仮にこれを静的にリンクしようとした場合はどういう風にすると出来るのでしょうか?或いは出来ないのでしょうか?


>動的ロードが必要なパターンはかなり少なくて、関数インターフェースが同じ複数のライブラリを使いまわしたいときなど。

例えば上記
#pragma comment(lib, "d3dx9.lib")
の場合だと
入ってない環境だと
d3dx9.dllがない→ロードが出来ない→起動できない
という事になるのではないかと思うのですが

こういった、入ってるかどうか分からないものに関してや
バージョンチェックとかが必要な場合はやらざるを得ませんよね?
(そういう意味で、それほど少なくもないと思うのですが)


で、今回知りたいのは


そういう意味では
WindowsXP以降に限定した場合は

winmm.lib
user32.lib
gdi32.lib

については動的ロードでなく
動的リンクで問題ない、と考えて良いのでしょうか?

お礼日時:2012/01/24 21:09

Windowsの場合ですが、静的リンクするのは、使用するDLLが標準でない(Windowsに最初から組み込まれているものではない)場合でDLLを一緒に提供できない場合や、バージョンに依存してしまう(古いDLLでないと動かない等)の場合など、何かしらの特別な理由がある場合のみで、通常は動的リンクを使用します。



静的リンクを使うと、自アプリにDLLのコードを組み込んでしまうので、アプリが肥大化しますが、稼動システム(のDLL)に依存しないものになります。つまり、WindowsUpdateによって組み込まれたセキュリティ対策も未対策となってしまいます。ただし、アプリに組み込んだDLL部分の処理が、そのシステムのDLLと不整合を起こして動かないことも考えられます。

動的リンクを使うと逆になって、アプリは必要最低限ですが、稼動システムに組み込まれているDLLに影響を受けます。パッチが当たると、アプリが思わぬ動作をすることもあります。
ただし、パッチがあたっている状態を使うことにもなるので、Windowsに組み込まれているDLLについては、アプリが同じでも、セキュリティ対策を行ったDLLを自動的に使うことになります。

そもそも、DLLは複数のアプリで使いまわせる共有ライブラリなので、静的リンクアプリだらけだと、同じコードがメモリに多重に展開されて、メモリの無駄使いかと。

なので、特別な理由が無ければ、通常は動的リンクです。

IDirectSound等のインターフェースについては、私も語れるほど詳しくは無く、アセンブラコードもまだ見てない(自分で検証してない)ので、今回はやめておきます。
まぁ、動いているのであれば、現状は「こうつかえばいいんだ」と覚えているだけでも良いかと。
後で気になったり、つまづいたら調べれば良いかと思います。

この回答への補足

あ、そうだ。
948個に対処する前にもうひとつ確認しておきたいのですが

キャッシュミス等の事も含めて

静的リンクと動的リンク
での「実行速度についていうと」
大抵前者の方が勝であろう、という事になるのでしょうか?


>そもそも、DLLは複数のアプリで使いまわせる共有ライブラリなので、静的リンクアプリだらけだと、同じコードがメモリに多重に展開されて、メモリの無駄使いかと。

この部分に関しては、常駐ではなく
かなり「主要なアプリ」で、ある程度のスペックを推奨という感じの位置づけになるので
今のメモリ使用量を見る限り

winmm.lib
user32.lib
gdi32.lib

のみについて考えて、この点は問題がないものと考えます。


>静的リンクを使うと、自アプリにDLLのコードを組み込んでしまうので、アプリが肥大化しますが、稼動システム(のDLL)に依存しないものになります。つまり、WindowsUpdateによって組み込まれたセキュリティ対策も未対策となってしまいます。ただし、アプリに組み込んだDLL部分の処理が、そのシステムのDLLと不整合を起こして動かないことも考えられます。

>ただし、パッチがあたっている状態を使うことにもなるので、Windowsに組み込まれているDLLについては、アプリが同じでも、セキュリティ対策を行ったDLLを自動的に使うことになります。


これらの点が問題ですが、それは実行ファイルのインストーラーやアップグレード権、更新手順とかを工夫すれば、それはそれで行けるかもしれない、という気がしてきます。
どっちのメリット・デメリットが勝るか、ですね。

補足日時:2012/01/24 01:01
    • good
    • 0
この回答へのお礼

ありがとうございます♪

と、いうことは、この状況
残る

winmm.lib
user32.lib
gdi32.lib

も動的リンクにしてしまえ~

ということになってくる、んでしょうか?

この方達はかなり基本的な感じで使いまくってたため
今外してみたら、どばーーーって948個ものエラーが出ました(苦笑)

これはちょっと面倒そうです
ただ、重複してるものも多いはずなので

検索と置換→クイック置換で
検索対象を現在のプロジェクト、あるいはソリューション全体にして

対象の関数名

目的の  名前空間::名前空間::関数ポインタ名

とかになるように一括変換してやればそれほどのことでもないかもしれませんが



対象の関数名、例えば
TrackMouseEvent
とすると
この名前のままこれを同じ引数、戻り値を持つような関数ポインタにしてしまうような方法ってないものですかね?
(理屈の上では、この場合winuser.hインクルードしなければいいってことになるでしょうが、そうなるとwindows.hもインクルード出来ないので)

お礼日時:2012/01/24 00:39

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!