• ベストアンサー

DLLが正しく呼び出せません (ToT)

こんにちは。よろしくお願いします。 環境は、WindowsXP Access2000/VBA にてプログラミングをしています。 現在、表題の「DLLが正しく呼び出せません」エラーに泣かされています。。。。 どなたかもし心当たりなどありましたらぜひアドバイスを下さい。 VBAにてシステムを作成していますが、その中で、普通に自分で書いた関数を 普通に?呼び出しているだけなのですが、表題のエラーが頻発してしまい困っています。 別に、外部DLLをDeclareしてそれを呼び出した時に出ている、という事ではないです。 普通に自分で書いた関数を呼び出すだけなんですが、ある関数を呼び出すと、 返ってくる時にこのエラーが発生するものがあります。(SubでもFunctionでも) 引数の型や戻り値の型は、呼び出し側と整合が取れています。(確実に一致しています) まったく原因がわからないので、例えばエラーの出た関数がSubの場合は 一応 Call をつけて呼び出してみたりするとその場はエラーがなくなったりして でも、またその関数の中を編集したりすると、いつのまにかまた その関数を呼び出した時に表題のエラーがでたりします。 もちろんコンパイルエラーはありませんし、SetしてNothingを忘れてメモリを壊している という事などもないつもりです。 (エラーのでる関数ではそもそもSetなどを使っていませんし) DLLの関数を呼び出すのではなく普通に標準モジュールなどに書いた自前の関数の呼び出しで 表題のエラーがでる原因として、なにか考えられる事はあるのでしょうか。 実際のソースを載せれないので申し訳ないですが、一般的な情報として 「DLLが正しく呼び出せません」エラーの原因となる事をどのような事でもけっこうですので 教えていただければ、と思います。 どうかよろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.1

VB/VBAから呼び出すDLLの関数は、Microsoft C/C++の用語で言うところのSTDCALL呼び出し規約でなければなりません。 呼び出し規約がSTDCALLでない関数(例えばcdecl呼び出し規約の関数)をVB/VBAから呼び出すと、関数の呼び出し自体は行われますが、関数の実行から戻ってきた時点で「DLLが正しく呼び出せません」エラーになります。 また、STDCALL呼び出し規約の関数であっても、呼び出し時に引数の数やサイズを間違えていると、やはり関数の実行から戻ってきた時点で「DLLが正しく呼び出せません」エラーになります。 このほか、呼び出された関数が何らかの理由(通常はプログラムミス=バグ)によりスタックポインタを通常あるべき値とは異なる値にして実行を終了すると、関数の実行から戻ってきた時点で「DLLが正しく呼び出せません」エラーになります。

kakugo
質問者

お礼

ご回答ありがとうございます。 今回の場合、やはり一番可能性が高いのが私のプログラムミスに起因しているものかと実は思っています。。 アドバイスいただいたように、引数の数やサイズ等を間違えているのかと思い何度も見直しては見たんですが…うむむむ…やはりあっているようなんです。 「スタックポインタをあるべき値以外にして実行を終了する」というのは、メモリ管理等を誤って不正な書き込みをしてしまう事によるものですよね。 例えば、それ以外にスタックポインタを壊して(?)しまうような例というのは思い当たりますでしょうか? いっその事そういう箇所があればいいんですが…どうにも見当たりません。。。 ※すみません。。無学で、STDCALL呼び出し規約とそうでない呼び出し規約が分かりませんでした。ちょっと調べて見ます。。 いくつかの原因を明確に書いていただきありがとうございます。 さらに具体的な例など、また、もし実際に体験してこう解決したなどの情報がございましたら、皆さんもよろしくお願いいたしますっ。

その他の回答 (1)

  • O_cyan
  • ベストアンサー率59% (745/1260)
回答No.2

WinXPではCALLBACK関数に操作させる関数は第一引数にHWND、第二引数にLPARAMをとるようなのですが・・。 引数が渡せないためエラーが起こっているのではと思います。その辺はどうでしょうか? Public Functionの宣言で第一引数だけの場合、第二引数を追加してFunctionの宣言を記述してみてはどうでしょう。

kakugo
質問者

お礼

ご回答ありがとうございます。 しばらく見ずにいてしまい返信が遅くなりまして申し訳ありません。 今回、DLLが正しく呼び出せませんエラーの起こる関数はいくつもあるのですが 共通点としては、Excel.Worksheet オブジェクトを引数とする関数であるという事みたいです。 Public のものも Private のものもエラーが出ていますが例えば Public Function fncTest( ByRef shtSheet1 As Excel.Worksheet, ByRef shtSheet2 As Excel.Worksheet ) As Long End Function というような関数です。 関数内ではとりあえず終わりまで正常に実行され、この関数から戻るときに DLL~エラーが発生します。なので、引数が渡せないためではないと思われるのです。 Excel のワークシートオブジェクトを引数に渡す事自体なにかまずいのでしょうか? (現在参照渡しなので、値渡しにしたらどうかという話も聞いたのですが 処理上、どうしても参照渡しで行いたいのです。) Excelのオブジェクトを引数にする場合の不具合情報などもしお持ちでしたらぜひよろしくお願いいたします。

関連するQ&A

  • 配列をDLLの戻り値としてVBAで受け取る書き方

    vbdll.dll: int * __stdcall arr() { int a[] = {1,2,3}; return a; } vba: Declare Function arr Lib "C:\temp\vbdll.dll" () As Long() Sub test() Dim ccc() As Long ccc = arr Debug.Print ccc(0) End Sub インデックスが有効範囲にありませんになります 配列をDLLの戻り値としてVBAで受け取る書き方を教えてください? 何卒、ご教授お願いします。

  • VBAでDLLが見つからないエラー

    CADのVBA(6.0)ですが、DLLが見つからないエラーが出ます ' こっちはエラーが出ない Public Declare Function SearchVBApath Lib _ "C:\Program Files\AppliTool\VB\DDDD.dll" (ByVal env As String, ByVal s As String) As Integer 'こっちだとエラーが出る Public Declare Function SearchVBApath Lib "DDDD.dll" (ByVal env As String, ByVal s As String)    As Integer VBAプロジェクトファイルとDLLは同じフォルダにおいてあります 上記のようにフルパスだとエラーが出ないのですがDLL名だけだとこの関数のところでエラーがでます このDLL関数宣言行の前の方には他のDLL関数も同じようにパス省略で記述しているのですがそちらにはエラーが出ません どなたかヒント下さい、よろしくお願いします。

  • VBAからDLLをCALLしたいのですが

    仕事上今まで蓄積されているFortranプログラムを効率よく使いたくDLL,VB,VBAにチャレンジしていますが, Intel(R) Fortran Compiler9.0で作成したDLLをEXCELのVBAからCALLしたところ 実行時エラー'49' DLLが正しく呼び出せません のエラーが表示されました。 このDLLはVisual Basic .NETで作成したVBからは正しくCALLできています。 色々原因を調べているのですがVBAからDLLの呼び出しとDLL内の計算は正しく行われておりDLLからVBAに戻るときにエラーになっているようです。 テストを行っているFortranとVBAのソースは以下です。VBAでDLLをCALL出来るように解決いたしたくご教授願お願いいたします。 (1)---- Fortran ソース --------------------------- subroutine DLL1(Q,QQ,QQQ) ! Expose subroutine DLL1 to users of this DLL ! !DEC$ ATTRIBUTES DLLEXPORT::DLL1 !DEC$ ATTRIBUTES ALIAS:'DLL1'::DLL1 ! Variables ! Body of DLL1 real*4 Q,QQ,QQQ QQ = Q*2 QQQ = Q**3 end subroutine DLL1 (2)----------- VBA ソース -------------------- Private Q As Single Private QQ As Single Private QQQ As Single Declare Sub DLL1 Lib "DLL1.dll" (ByRef Q As Single, ByRef QQ As Single, ByRef QQQ As Single) Sub Macro1() ChDrive ActiveWorkbook.Path ChDir ActiveWorkbook.Path Q = 2# Call DLL1(Q, QQ, QQQ) Cells(5, 2) = Format(Q, "#####.#0") Cells(6, 2) = Format(QQ, "#####.#0") Cells(7, 2) = Format(QQQ, "#####.#0") End Sub

  • VCで作成したDLLの使用

    VCで作成したDLLの使用 VC6.0で作成されたDLLファイルを使いたいのですが _stdcallで記述されたものではなく DllMainで記述されたものなのですが、 VBから呼び出す事は可能でしょうか? 普通にdeclare functionで呼び出そうとすると、 「エントリfnchogeがDLLファイル hoge.dll内に関数が見つかりません。」 とエラーがでるだけでした。 VB6.0SP3 Windows2000

  • VB(6.0)で作成したDLLをVB(.Net)で呼び出す方法

    VB(6.0)で作成したDLLをVB(.Net)で呼び出すのに Public Declare Function 関数名 Lib "~.dllのパス"               (ByVal ・・・) As 型 このように呼び出してみているのですが 上手くいきません。整数データの変更も しました。 このDLLを呼び出せないと次に進めないので 本当に困っています。 よろしくお願いします。

  • エクセルで自作 DLL の作り方・使い方

    エクセルで使う自作DLLを作ろうとしております。コンパイラーはBorlandでBCC Developerです。 ネットで検索しC++では例えば: extern "C" __declspec(dllexport) int addNum( int _i, int _j ) {return _i+_j;} のようなものを作りました。 ただエクセルVBA上でauto_open イベントにapplication.registerxll("xxx.dll") をしても、上記関数を認識しません・・VBA上に: Public Declare Function addNum Lib "xxx.dll" (.... とすると認識するのですが、上記VBA内での関数の定義を省きたいのですが・・ どなたかご教授いただけますでしょうか?おそらくC++の書き方の問題だとは思っていますが、エクスポートのやり方がイマイチわかっておりません。VBA上でも呼び方がわかっていないのでどなたか教えていただければと思います。

  • DLL VBとC++

    VBAからVC++2005のDLLを呼び出すプログラムを書いています。 VB側で作成したcpp_proc関数を呼ぶとVBアプリ自体が落ちました。 DLLのreturnの直前に以下のMessageBoxで表示させるとそこまでは表示され、 リターンを押すと、落ちました。 VB側の引数の値 String * 8192が悪いのでしょうか? return直前まで動作していたので、DLLの戻り値に何か原因があるのでしょうか? ついでの質問ですが、DEFの @1は無くても動くのでしょうか? 意味が知りたいです。 // ----- C++ (DLL側) ----- int __stdcall cpp_proc(LPCSTR inp, LPSTR out) { ... 省略 MessageBox(0, "ここまで通過", "debug", MB_OK); return 0; } // ----- DEF ----- LIBRARY "example" DESCRIPTION 'テスト' EXPORTS ; 明示的なエクスポートはここへ記述できます cpp_proc @1 '----- VB側 ----- Public Declare Function cpp_proc Lib "example.dll" _ (ByVal inp As String, ByRef out As String) As Integer Public Sub Test() Dim ret As Integer Dim inp As String Dim out As String * 8192 ret = cpp_proc(inp, out) MsgBox("ret=[" & Cstr(ret) & "]"); End Sub

  • DLL作成後VBAで使用しようとするとエラーが出ます

    エントリxxがDLLファイルyy内に見つかりません。とエラーが出ます。 複雑な処理をCでやろうとして基本的な箱を作ろうとしたのですがうまくいきません。どなたか教えていただけないでしょうか? C側 #define DLL_EXPORT __declspec(dllexport) extern "C" { DLL_EXPORT void kinou(int a); } void kinou(int a) { //処理 } 呼び出し規約はstdcallしています。 VBA側 Declare Sub kinou Lib ".\test.dll[ (フルリンクしています)] " (ByVal a As Integer) Sub test() Call tasu(10) End Sub

  • 自作DLLをエクセルVBAで使用したい

    こんにちは。 自作DLLをエクセルVBAで使用したいのですが、知識不足でうまく動かせません。どうぞお知恵をお貸しください。 例えば足し算をするCのプログラムを以下のように作ります。ファイル名は"wa.c"とします。 #define EXPORT __declspec(dllexport) __stdcall EXPORT double wa(double a,double b) { return(a+b); } これをコンパイルして、DLLファイル"test.dll"を作ります。 gcc -shared -o test.dll wa.c エクセルVBAのモジュールには次のように記述しました。 Declare PtrSafe Function wa Lib "test.dll" (ByVal a As Double, ByVal b As Double) As Double ここで作成した関数をワークシート関数として呼び出したいのですが、ワークシート上での返り値は常にゼロになってしまいます。例えば、ワークシートのセルに"=wa(1.2,3.5)"と記入すると、"4.7"を返してほしいところですが、ゼロとなってしまいます。ワークシート関数として正しく動作させるにはどうしたらよいでしょうか? ちなみに、この関数をエクセルVBAのサブルーチンで使うことはできます。例えばこんな感じです。 Sub test() x = 1.2 y = 3.5 Call MsgBox(wa(x, y)) End Sub また、上記の"test.dll"を他のCのプログラムから呼び出すことも正しくできます。 なお、64bitのエクセルを使っています。Cのコンパイラも64bitです。 どうぞよろしくお願いいたします。

  • GetNextWindowがDLLファイルUser32.dll内に見つかりません。

    前のウィンドウのハンドルを取得したいのですが上記のタイトルにあるエラーメッセージが出ます。 VB6 XPproでやってます。 User32.dllはsystem32フォルダーの中にあるのですが。 Private Declare Function GetNextWindow Lib "user32.dll" (ByVal hWnd As Long, ByVal wCmd As Long) As Long sub tes() n=GetNextWindow(me.whnd,3) end sub