ActiveXからDLLを呼出すには?

解決


えむえむ  2004-08-20 06:21:48  No: 115787

VBで作成したEXEからVC++で作成したDLLを呼出して実行していました。 
それと同じ関数をActiveX(EXE)から呼出すと
"実行時エラー'-2147352560(80020010)'"のメッセージが表示され、
エラーとなってしまいます。 

回避方法が分かりません。
ご教授宜しくお願いいたします。 

バージョンはVB6とVC6です。 
環境はWindows XPです。 

VB側のソース 
宣言部 
Private Declare Function TestFunc Lib "TestLib" (ByVal param1 As String, ByVal param1 As Long, ByVal param1 As String, ByVal param1 As String) As Long 

ソース部 
Dim lRet As Long 
Dim param1 As String 
Dim param2 As Long 
Dim param3 As String 
Dim param4 As String 

lRet = TestFunc(param1, param2, param3, param4) 

C側のソース 
extern "C" __declspec(dllexport) long TestFunc(char *param1, long param2,char *param3,char *param4) 

宜しくお願いいたします。


Dental  2004-08-20 07:23:30  No: 115788

> "実行時エラー'-2147352560(80020010)'"のメッセージが表示され、
エラーコードからすると…

HRESULT:=DISP_E_BADCALLEE (0x80020010)
en-us:="Invalid callee."
ja:="呼び出し先が無効です。"
Severity:=Fail
Facility Code:=0x2
Status Code:=0x10

ですね。

> 回避方法が分かりません。
すみません。私もわかりません。
(わからないなら回答するな、という意見が聞こえてきそう…)

・StartMode が vbSModeStandalone の場合にはエラーになるのか?
・StartMode が vbSModeAutomation の場合にはエラーになるのか?
・ActiveX EXE内で TestFunc を呼ばない時は、エラーにならないのか?
・ActiveX EXE内で TestLib のフルパスを指定してみてもエラーになるか?
・ActiveX EXE内で TestFunc 以外のDLLを呼び出した場合は問題無いのか?
・プロセスの実行ユーザーに Administrators グループ権限を与えた場合はどうか?
・エラー発生時の Err.LastDllError と Err.Source は何になっているか?
・最適化無しのネイティブコンパイルや、P-Code コンパイルなどに変更してみても結果は同じか?


えむえむ  2004-08-21 22:57:49  No: 115789

えむえむです。
アドバイスありがとうございます。
指摘いただいた項目を試しましたが、下記のようになりました。

・StartMode が vbSModeStandalone の場合にはエラーになるのか?
エラーになります。
・StartMode が vbSModeAutomation の場合にはエラーになるのか?
エラーになります。
・ActiveX EXE内で TestFunc を呼ばない時は、エラーにならないのか?
エラーは発生しません。
・ActiveX EXE内で TestLib のフルパスを指定してみてもエラーになるか?
フルパス指定しても駄目でした。
・ActiveX EXE内で TestFunc 以外のDLLを呼び出した場合は問題無いのか?
Win32のDLL(FindWindow)の予備だしはうまくいきます。
・プロセスの実行ユーザーに Administrators グループ権限を与えた場合はどうか?
結果は同じでした。
・エラー発生時の Err.LastDllError と Err.Source は何になっているか?
Err.LastDllError = 0
Err.Source はActiveX名になっています。
・最適化無しのネイティブコンパイルや、P-Code コンパイルなどに変更してみても結果は同じか?
結果は同じでした。

あれから色々と試したのですが、不思議なことにVBおよびVCの引数を
なくしてみるとDLL呼出しが正常に動作します。
下記に例を示します。

VB側のソース
Private Declare Function TestFunc Lib "TestLib" () As Long 

Dim lRet As Long 

lRet = TestFunc() 

VC側のソース 
extern "C" __declspec(dllexport) long TestFunc() 

引数がないので当然処理はうまくいかないのですが、DLL呼び出しは正常に
動作します。
なぜでしょうか?
ほとほと困っています。


しんこう  2004-08-21 23:57:09  No: 115790

効果があるかどうか分かりませんがC側の宣言を下記のようにしてみたらどうでしょうか?

__declspec(dllexport) long __stdcall TestFunc(char *param1, long param2,char *param3,char *param4)


えむえむ  2004-08-22 01:19:49  No: 115791

ついに解決しました!!
以下のように宣言を変更することでうまくいきました。

VB側宣言
Private Declare Function TestFunc Lib "TestLib" Alias "_TestFunc@16" (ByVal param1 As String, ByVal param1 As Long, ByVal param1 As String, ByVal param1 As String) As Long 

VC側宣言
extern "C" __declspec(dllexport) long __stdcall  TestFunc(char *param1, long param2,char *param3,char *param4)

MSDNに__stdcallの使用方法がのっていたのですが、@以降の設定方法が
意味不明でした。
引数のバイト数を総計すればよかったんですね。
しかし、通常EXEではAliasは必要なくてActiveXでは必要になるのは
なぜなんでしょうね。(わかりにくいな〜)

皆様、ヒントやご協力ありがとうございました。


えむえむ  2004-08-22 01:20:56  No: 115792

すみません。
解決印をチェックしてませんでしたので、再送信します。


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加