VC++で作成したDLLをVBで呼び出したときに生じるアプリケーションエラーを回避するには?

解決


ポリアセチレン  2004-11-09 07:57:31  No: 55029

初めまして,ポリアセチレンと申します.

  VBから,フーリエ変換を行うプログラムでVC++でつくったDLLを呼び出したところ,「"0x04246c81"の命令が"0x04246c81"のメモリを参照しました。メモリが"read"になることはできませんでした。」と表示されて,アプリケーションが終了してしまいました.DLLを使って確保したメモリの作成・開放等がうまくいっていないというのは見当がつきますが,具体的にどうすればよいのかが分かりません.

  なお,フーリエ変換のプログラムはhttp://www.fftw.org/install/windows.htmlからダウンロードできるfftw-3.0.1-w32-pl1.zipを利用しました.自作したDLLは,VBから取得したデータをフーリエ変換を行うDLLに渡すだけのものです

  それほど長いプログラムではないので,もしお時間があるようでしたら,職説ソースを見て,アドバイスを頂けると幸いです.
  どうぞ宜しくお願いいたします.


ポリアセチレン  2004-11-09 08:27:51  No: 55030

訂正:「職説」→「直接」でした.

  なお,VB,VC++のソースは以下の通りです.
  どうぞ宜しくお願いいたします.

---[VB] Form1.frm----------------------------------------------

Option Explicit

Private Type fftw_complex
    Re As Double
    Im As Double
End Type

Private Declare Function dft_1d Lib "FFTW.dll" _
(ByVal n As Long, FFTWin As fftw_complex, FFTWout As fftw_complex, ByVal sign As Long)

Dim n As Long
Dim FFTin(2 ^ 16 - 1) As fftw_complex
Dim FFTout(2 ^ 16 - 1) As fftw_complex
Dim sign As Long
Const FFTW_FORWARD = -1
Const FFTW_BACKWARD = 1

Private Sub Command1_Click()

Dim i As Long
Dim j As Long

    Open "Sample.txt" For Input As #1
    Open "SampleOut.txt" For Output As #2

    i = 0
    Do While Not EOF(1)
        Input #1, FFTin(i).Re
        FFTin(i).Im = 0
        i = i + 1
    Loop
    Close #1

    Call dft_1d(i - 1, FFTin(0), FFTout(0), FFTW_FORWARD)

    For j = 0 To i - 1
        Write #2, FFTout(i).Re, FFTout(i).Im
    Next
    Close #2

End Sub

---[VC++] FTTW.cpp(一部抜粋)------------------------------

FFTW_API void __stdcall dft_1d(int n, fftw_complex *FFTWin, fftw_complex *FFTWout, int sign)
{
        fftw_complex *in, *out;
        fftw_plan p;

        in  = (double (*)[2])fftw_malloc(sizeof(fftw_complex) * n);
        out = (double (*)[2])fftw_malloc(sizeof(fftw_complex) * n);
        //<sign> FFTW_FORWARD(-1), FFTW_BACKWARD(1)  <flags> FFTW_ESTIMATE, FFTW_MEASURE

        in = FFTWin;
        p = fftw_plan_dft_1d(n, in, out, sign, FFTW_ESTIMATE);
        fftw_execute(p); /* repeat as needed */
        FFTWout = out;

        fftw_destroy_plan(p);
        fftw_free(in); fftw_free(out);
}

---[VC++] FTTW.h -----------------------------------------

#ifdef FFTW_EXPORTS
#define FFTW_API __declspec(dllexport)
#else
#define FFTW_API __declspec(dllimport)
#endif

#include "fftw3.h"

        FFTW_API void __stdcall dft_1d(int n, fftw_complex *in, fftw_complex *out, int sign, unsigned flags);

---[VC++] FFTW.def ------------------------------------------

LIBRARY fftw.dll

EXPORTS
  dft_1d

-----------------------------------------------------------------


YuO  2004-11-11 10:35:18  No: 55031

とりあえず,KBを漁ってみるくらいはした方がよいです。

Knowledge Base 410837
[VB5] Visual Basic 5.0 から呼び出し可能な DLL の作成例
http://support.microsoft.com/default.aspx?scid=kb;ja;410837

根本的に,構造体の配列を受け取るにはSAFEARRAYを使います。

でもって,

> FFTW_API void __stdcall dft_1d(int n, fftw_complex *FFTWin, fftw_complex *FFTWout, int sign)
(略)
>     FFTWout = out;
>
>     fftw_destroy_plan(p);
>     fftw_free(in); fftw_free(out);
> }

何がしたいんでしょう。
FFTWoutに代入する行為も意味がわからなければ,
直後にout(=FFTWout)のメモリを解放する行為の意味もわかりません。


ポリアセチレン  2004-11-12 01:23:04  No: 55032

この話の続きは以下のリンク先で継続して行っております.
  

http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110022.txt


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

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






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