皆様初めまして。
うまい題をつけられずすいません。
VC++にて、
.dllと.idlをもらっていて、その中の処理を呼び出したいのだが、うまくいかないという
内容です。
ネットやMSDNで色々調べたんですが、私の理解力では解決できませんでした。
お力お貸しください。
----------
試み1
.idlをコンパイルしてできたヘッダファイルを見ていると、(下に抜粋しました)
以下のような処理で呼び出すのだと思ったのですが、GetProcAddress()がうまく行きま
せんでした。
-Source-------------
IKeyVerification *xKeyVerif;
HMODULE hDll = LoadLibrary(TEXT(KeyVerification.dll));
xKeyVerif = GetProcAddress( hDll,IKeyVerification)
xKeyVerif->Verify(addr, usr, &result);
-Source-------------
そこでdllをdumpbinしてみると、以下の関数しか無いようです。
DllCanUnloadNow、DllGetClassObject、DllRegisterServer、DllUnRegisterServer
これは、GetProcAddress()で指定できる関数がこれだけという意味ですよね?
----------
試み2
DllGetClassObject()でアドレスを取り出すのかと思って、以下のような試みもしてみ
ましたが、
コンパイルはexternが有るので通りますが
リンクでCLSID_KeyVerificationとIID_IKeyVerificationが見つからずにうまく行きま
せん。
FARPROC func = GetProcAddress(hDllLib, DllGetClassObject);
((DllGetClassObject)func)(CLSID_KeyVerification, IID_IKeyVerification,
(void**)&xKeyVerif);
環境はWinXP VC++2005です。
-idlからできたヘッダファイル----------------------
typedef interface IKeyVerification IKeyVerification;
typedef class KeyVerification KeyVerification;
#include oaidl.h
#include ocidl.h
extern C{
void * __RPC_USER MIDL_user_allocate(size_t);
void __RPC_USER MIDL_user_free( void * );
EXTERN_C const IID IID_IKeyVerification;
MIDL_INTERFACE(D3B3117D-7834-4A67-B25B-6D7178FF2CA7)
IKeyVerification : public IDispatch
{
public:
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Verify(
/* [in] */ BSTR ADDR,
/* [in] */ BSTR USR,
/* [retval][out] */ VARIANT_BOOL *Result) = 0;
};
/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE
IKeyVerification_Verify_Proxy(
IKeyVerification * This,
/* [in] */ BSTR ADDR,
/* [in] */ BSTR USR,
/* [retval][out] */ VARIANT_BOOL *Result);
void __RPC_STUB IKeyVerification_Verify_Stub(
IRpcStubBuffer *This,
IRpcChannelBuffer *_pRpcChannelBuffer,
PRPC_MESSAGE _pRpcMessage,
DWORD *_pdwStubPhase);
EXTERN_C const IID LIBID_KEYVERIFICATIONLib;
EXTERN_C const CLSID CLSID_KeyVerification;
class DECLSPEC_UUID(342B4981-D0AB-48FF-B8BA-E012D780AE0B)
KeyVerification;
/* Additional Prototypes for ALL interfaces */
unsigned long __RPC_USER BSTR_UserSize( unsigned long *,
unsigned long, BSTR * );
unsigned char * __RPC_USER BSTR_UserMarshal( unsigned long *, unsigned
char *, BSTR * );
unsigned char * __RPC_USER BSTR_UserUnmarshal(unsigned long *, unsigned
char *, BSTR * );
void __RPC_USER BSTR_UserFree( unsigned long *,
BSTR * );
}
-idlからできたヘッダファイル----------------------
説明ないのかよ!
説明なしヘッダファイルなしで使えって不親切だな。
COMっぽいな。
dllをインストールしたい場所において登録してないのか。
regsvr32で登録。
IID_IKeyVerificationはD3B3117D-7834-4A67-B25B-6D7178FF2CA7じゃないのかな。
#import 使っても駄目?
うまくいけば楽になると思う。
俺はあまりCOM使わないから詳しくは知らない。
知らない事にまで、口出す必要は…
CoInitialize();
IKeyVerification * pkv = NULL;
CoCreateInstance( CLSID_KeyVerification, NULL, CLSCTX_INPROC_SERVER,
IID_IKeyVerification, reinterpret_cast< void ** >( &pkv );
pkv->Verify( ... );
pkv->Release();
CoUninitialize();
こんな要領で使います。
エラー処理は省いているので、適宜補ってください。
間違えた。
誤:CoInitialize();
正:CoInitialize( NULL );
シャノンさんありがとうございました。
お教え頂いた手順でやってみましたがうまくいきません。
importを追加してコンパイル・リンクはOKなのですが、
実行するとpkv->Verifi()のラインで不正終了になってしまいます。
試しにpkv->Verifi()をコメントアウトしてpkv->Release()だけにしても同じく死亡しま
す。
CoCreateInstance()の返値pkvはNULLでは無いのですが、
ブレイクして値を見ると、
pkv 0x0012f7e0 →IDispatch{...} →IUnknown{...} →__vfptr 0x00000000 →[0]
CXX0030:エラーです:式を評価できません (以下0~3まで同じ)
となっていて、うまく取り出せていないみたいです。
もうしばらくお付き合い頂けたら助かります。
----------
//#include KeyVerification_h.h
#import KeyVerification.dll no_namespace named_guids raw_interfaces_only
void func()
{
VARIANT_BOOL xResult;
CoInitialize(NULL);
IKeyVerification *pkv = NULL;
CoCreateInstance(CLSID_KeyVerification, NULL, CLSCTX_INPROC_SERVER,
IID_IKeyVerification, reinterpret_cast< void ** >(&pkv));
if(pkv = NULL) {
AfxMessageBox(TEXT(とりだせない));
return;
}
pkv->Verify(TEXT(00aA80DB34B3),TEXT(EFBE62CBC1F312AE),&xResult);
pkv->Release();
CoUninitialize();
}
----------
そのコードは本当にコピペですか? 書き写しミスがありませんか?
であれば、
> CoCreateInstance()の返値pkvはNULLでは無いのですが、
CoCreateInstance 直後が NULL でなくとも、
> if(pkv = NULL) {
ここで NULL にしてしまっています。
あと、CoCreateInstance が成功したかどうかは、戻り値で判断するようにしましょう。
> if(pkv = NULL) {
=ではなくて==だと思うが typo かな?それともほんとうにこうなっている?
すいません、ifの=はカキコミでのtypoです。
今度はソースそのままコピペします。
以下のように返値で判断するように修正したところ、
CoCreateInstance()がNULLを返してきていたみたいです。
何でNULLになるのか、これから自分でも調べてみます。
とりあえずimportのdllのパスをCのルートにコピーしてトライしましたがダメでしたx。
----------
#import c:\KeyVerification.dll no_namespace named_guids raw_interfaces_only
void func()
{
VARIANT_BOOL xResult;
HRESULT xxx;
CoInitialize( NULL );
IKeyVerification *pkv = NULL;
xxx = CoCreateInstance(CLSID_KeyVerification, NULL, CLSCTX_INPROC_SERVER,
IID_IKeyVerification, reinterpret_cast< void ** >( &pkv));
if( !SUCCEEDED(xxx)) {
AfxMessageBox(TEXT(とりだせない));
return;
}
pkv->Verify(TEXT(00aA80DB34B3),TEXT(EFBE62CBC1F312AE),&xResult);
if (xResult) {
AfxMessageBox(TEXT(あ));
}
else {
AfxMessageBox(TEXT(い));
}
pkv->Release();
CoUninitialize();
----------
> 以下のように返値で判断するように修正したところ、
> CoCreateInstance()がNULLを返してきていたみたいです。
そのときの戻り値の値は何ですか?
ちなみに、SUCCEEDED の反対で FAILED というマクロもあります。
wclrp ( 'o') さんの書き込みにありますが、
> regsvr32で登録。
は行ってますか?
> wclrp ( 'o') さんの書き込みにありますが、
>> regsvr32で登録。
> は行ってますか?
COMを使うならこれ大事です。
COM周りの勉強も少しはした方が良いと思いますよ。
作るまで行かなくても使える位にはなっておいた方が良いです。
レス遅くなりましてすいません。
結局regsvr32の登録がされていませんでした。
(色々試している間に、外してしまっていたらしい)
皆様色々アドバイスありがとうございました。
今回は「とりあえず動く物を」という事で、下調べや勉強不足のまま
始めてしまっていました。
これから、これまでのトラブル部分を再勉強します(x