かなり初歩的な質問です。
色々勉強中なのでご容赦下さい。
開発環境はVisualC++.net + SDKにてWindowsGUIプログラムを作っています。
目的としてはUNLHAを使ってファイルの圧縮・解凍動作をさせようと思います。
UNLHAは配布場所より入手してインストールしました。
LHAファイルを解凍させる為にDLLをLoadLibrary()で動的に読み込んで動作させたいので
すがうまくいきません。
プログラムを作る為にやった作業としては・・・
(ここから知識が無い為正解の作業をしているのか不明です)
・UNLHA32.Hをインクルード(下記記述をメインファイルの頭に記入)
#include <winsock.h>
#include <windows.h>
#include <wininet.h>
#include resource.h
#include C:\\Program Files\\ArchiverDLL\\UNLHA32\\UNLHA32.H
・libをプロジェクトに追加
プロジェクトのプロパティより[リンカ]-[入力]-[追加の依存ファイル]にUNLHA32.LIBを
記述。
この状態で動くかテストする為にビルド。すると以下のようなエラーメッセージが出た。
C:\\Program Files\\ArchiverDLL\\UNLHA32\\UNLHA32.H(630) : error C2061: 構文エラ
ー : 識別子 'time_t'
C:\\Program Files\\ArchiverDLL\\UNLHA32\\UNLHA32.H(631) : error C2143: 構文エラ
ー : ',' が '*' の前にありません。
//---エラーここまで
time_tが定義されているファイルをインクルードしてない?からこのようなエラーが出て
いると思います。
で質問としては
「こういう手順で作業していますが方向性は合っている?」
「ヘッダーファイルは他に何をインクルードすべきなのか?wchar.hあたりでしょう
か?」
という事です。
意図する作業が出来るまで細かい事を質問すると思いますがよろしくお願いします。
>「こういう手順で作業していますが方向性は合っている?」
あっていると思います。
>「ヘッダーファイルは他に何をインクルードすべきなのか?wchar.hあたりでしょう
か?」
ドキュメントになければ、エラーが出る識別子が宣言されているヘッダーファイルを順番
に追加すればよいです。
>time_tが定義されているファイルをインクルードしてない?からこのようなエラーが出
ていると思います。
ならインクルードしてください。
>「ヘッダーファイルは他に何をインクルードすべきなのか?wchar.hあたりでしょう
か?」
使うならインクルードすればいい。
使わないなら何のためにインクルードするの?
追記、この手順は静的リンクの手順です。
動的リンクの場合、「libをプロジェクトに追加」が不要になります。
ダウンロードしてみましたか?
ドキュメントがかなりありました。
一度ダウンロードして解凍してみるのも必要だと思います。
どの程度の知識があってやっているんだろうというのも気になりますね。
普通に動くWindowsアプリがSDKで作れるレベルでライブラリの使い方で
悩んでいるのか、それともそれ以前のレベルだけといきなりライブラリを
使おうとしているのか。
それによって説明するにしても説明の深さが変わってくるような気がします。
もしアプリの作成もまだ良くわからないという話ならもっと簡単なレベルの
アプリからステップアップした方が良い様な気もしますし。
静的にDLLをリンクする方法と動的にDLLリンクする方法を調べて
きちんと整理して理解する必要がありそうですね。
あと、質問している内容そのものはライブラリを動的に使おうとしている
という話には直接関係ないレベルだと思います。
コンパイルエラーの内容に関しては単にインクルードが足りないだけなのか、
インクルード順が悪いだけなんでしょうから。
ご返事ありがとうございます。
DLLを呼び出すコードは全く初めてでしたので、おかしな所でつまずいていたようでし
た。
ひとまず第一段階としてUNLHAの中のUnlhaGetVersion関数を使う所まで出来ました。
質問の最初の状態から少しは進めたと思います。
テストとして書いたプログラムを以下に記述します。(おかしな所が無い事を祈ってま
す)
//-----ここから------
DWORD dwVersion;
char szStrBuff[64];
//参考:unlha.hの記述 WORD WINAPI _export UnlhaGetVersion(VOID);
WORD (_stdcall *UnlhaGetVersion)(void);
//---明示的呼び出し
HINSTANCE hDll;
hDll=LoadLibraryEx(Unlha32,NULL,0);//LoadLibraryでもOK
if(hDll==NULL){
wsprintf(szBuff,Unlha32.DLL読み込めず);
DISP(szBuff);
return FALSE;
}
UnlhaGetVersion=(WORD(_stdcall *) (void))GetProcAddress(hDll,UnlhaGetVersion);
if(UnlhaGetVersion==NULL){
DISP(UnlhaGetVersion関数が読み込めず);
FreeLibrary(hDll);
return FALSE;
}
//---暗示的なDLLの呼び出しの場合はLIBファイルを構成に加え、ヘッダーファイルに以
下の2行を加えると使用できる
//#include <time.h>
/#include C:\\Program Files\\ArchiverDLL\\UNLHA32\\UNLHA32.H
dwVersion=UnlhaGetVersion();
wsprintf(szStrBuff,%d,dwVersion);
DISP(szStrBuff);
//-----ここまで------
DLLファイル中の関数のポインタに辿り着けばいいという考え方なのかな~?と思ってま
す。
今日はもうタイムアップですので中間報告を書いて寝ます。
初めての場合は特に理由のない限り、「暗示的なDLLの呼び出し」の方法を薦めます。
「明示的なDLLの呼び出し」は、DLLの作り方によって変わります。
ITOさんこんにちわ。
どちらの方式でDLLを読み込むのか迷ったのですが、
1)外部DLLを使うのはUNLHAの操作のみ。仕様頻度も高くない。しかし、必ず使う。
2)プログラムサイズを小さくしておきたかった。
3)色々なDLLの呼び出し方法を会得しておきたかった。
との理由から明示的な呼び出しを選択しました。
幸いにも明示的、暗示的両方の使い方が、何となく分かったような気がします。
今日何とか意図する動作をするものが出来たのでそのコードを乗せてこの質問を解決にし
ます。
int nRet;
char szStrBuff[64];
char szCmdline[64];
memset(szStrBuff,0,sizeof(szStrBuff));
memset(szCmdline,0,sizeof(szCmdline));
//unlha.hの記述 int WINAPI _export Unlha(HWND,LPCSTR,LPSTR,DWORD);
int (_stdcall *Unlha)(HWND,LPCSTR,LPSTR,DWORD);
//---明示的呼び出し
HINSTANCE hDll;
hDll=LoadLibraryEx(Unlha32,NULL,0);//LoadLibraryでもOK
if(hDll==NULL){
wsprintf(szStrBuff,Unlha32.DLL読み込めず);
DISP(szStrBuff);
return FALSE;
}
Unlha=(int (_stdcall *) (HWND,LPCSTR,LPSTR,DWORD))GetProcAddress(hDll,Unlha);
if(Unlha==NULL){
DISP(Unlha関数が読み込めず);
FreeLibrary(hDll);
return FALSE;
}
strcat(szCmdline,e);//解凍モード
strcat(szCmdline, .\\etc\\test.lzh);//書庫名
strcat(szCmdline, -a1 -c);//オプション
strcat(szCmdline, .\\etc\\);//解凍先
nRet=Unlha(hWnd,szCmdline,szStrBuff,sizeof(szStrBuff));
if(nRet!=0){
DISP(エラー);
return FALSE;
}
DISP(解凍OK);
return TRUE;
FreeLibrary(hDll);
//---ここまで。
オプションについてはもう少し考える余地があるなと思っています。
ちぇっくし忘れてました