1

私は何時間もこれをやろうとしました。私は Fortran コードを持っており、C シャープ プロジェクトでそれを使用したいと考えています。

  subroutine lean(nx,nlam,flmin,
  ulam,thr,isd,intr,maxit,lmu,a0,ca,ia,nin,rsq,alm,nlp,jerr)
  real x(no,ni),y(no),w(no),vp(ni),ca(nx,nlam),cl(2,ni)                 
  real ulam(nlam),a0(nlam),rsq(nlam),alm(nlam)                          
  integer jd(*),ia(nx),nin(nlam)                                        
  real, dimension (:), allocatable :: vq;  
  ...

このサブルーチンをインポートするために、C シャープで次のコードを使用しました。

    [DllImport("lean.dll", CallingConvention = CallingConvention.Cdecl)]
    private static extern void lean_(
        ref int nx, 
        ref int nlam,
        ref float flmin,
        ref float[] ulam,
        ref float thr, 
        ref int isd,
        ref int intr, 
        ref int maxit, 
        ref int lmu,
        [In,Out]  ref float[] a0,
        [In,Out]  ref float[,] ca,
        [In,Out]  ref int[] ia,
        [In,Out]  ref int[] nin,
        [In,Out]  ref float[] rsq,
        [In,Out]  ref float[] alm, 
        ref int nlp, 
        ref int jerr);

そして、私はこのエラーを受け取りました

保護されたメモリを読み書きしようとしました。これは多くの場合、他のメモリが破損していることを示しています。

この関数には、処理方法がわからない 2 つのパラメーターがあります。jd は jd(*) 型で、vp は割り当て可能です。残りは問題ないはずです。これらのパラメーターの種類を処理する方法を知っている人はいますか? ありがとう。

4

1 に答える 1

1

呼び出し規約は、StdCall または ThisCall のいずれかである必要があります。Cdecl は、呼び出し元がパラメーターのスタックとスタック解除を担当することを意味します。StdCall は、呼び出し元がスタックを担当し、呼び出し先がアンスタックを担当することを意味します。ThisCall は、最初のパラメーターを ECX に入れ、残りのスタックをプッシュすることで時間を節約します。Cdecl は、C/C++ および varargs の概念を使用するプログラミング言語でのみ使用されます。それ以外の地域では StdCall が使用されます。ThisCall を使用するものがわからない。

おそらく、呼び出し全体に安全でない {} を配置する必要があります。

jd と vq は Fortran によって内部的に割り当てられるため、気にする必要はありません。おそらく、それらは終了前に割り当て解除されます。Fortran には独自のヒープがあります。

マルチスレッドの場合は、配列を固定として宣言する必要があります。Fortran がそれらを処理しているとき、それらは動き回ることができません。

于 2013-04-13T17:17:30.383 に答える