0

glmnet ライブラリ ( http://cran.r-project.org/web/packages/glmnet/index.html ) をラップして、C# でモデルのスパース一般線形モデルを解決できるようにしようとしています。ただし、元の関数には 20 個ほどのパラメーターがあるため、データの受け渡し方法をテストするための小さなサブルーチンから始めました (Fortran はまったく初めてです)。残念ながら、私は常に AccessViolationException を受け取ります。

コードは次のとおりです。

Fortran サブルーチン。-m64 オプションを使用して、Rtools ( http://cran.r-project.org/bin/windows/Rtools/ ) に付属の gfortran コンパイラを使用して dll にコンパイルします (はい、かなり処理するので 64 ビットが必要です)。大量のデータ)。はい、 i を使用すると範囲外になる可能性があります...ただし、これはテスト用です。

subroutine testaaa  (f,i,fa,ia)
real fa(i)                                                      
integer ia(i)
ia(1) = 1337
ia(i) = 666
fa(1) = 8.15
fa(i) = 333
end subroutine testaaa

C# PInvoke コード:

[DllImport("ftest.dll", EntryPoint = "testaaa_", CallingConvention = CallingConvention.StdCall)]
public static extern void Test(
    [MarshalAs(UnmanagedType.R4)] float f,
    [MarshalAs(UnmanagedType.I4)] int i,
    IntPtr fa,
    IntPtr ia);

そして、これがどのように呼び出されるかです:

var fa = new float[4];
var ia = new int[4];
IntPtr faPtr = Marshal.AllocHGlobal(fa.Length * sizeof(float));
Marshal.Copy(fa, 0, faPtr, fa.Length);

IntPtr iaPtr = Marshal.AllocHGlobal(ia.Length * sizeof(float));
Marshal.Copy(ia, 0, iaPtr, ia.Length);

GlmnetDllWrapper.Test(0.4f, 4,faPtr,iaPtr);

また、配列を直接渡して [MarshalAs(UnmanagedType.LPArray)] 属性を与えようとしました。何もうまくいきませんでした。

どこから始めるべきか、何を変更すべきか、何か提案はありますか?

更新 1: float と int のみを渡しても、既に例外が発生しています:

subroutine testbbb  (f,i)
i = 815
f = 8.15
return
end subroutine testbbb

C# の Pinvoke と呼び出しは、それに応じて変更されます。私は何を間違っていますか?

4

2 に答える 2

-1

http://msdn.microsoft.com/en-en/library/chfa2zb8%28v=VS.80%29.aspx (安全でないコード)を確認し、プロジェクト設定を試してみて くださいProject / Properties / Build:allow安全でないコード。ただし、その結果に注意してください。:)

更新:「遊んで」はいけません-つまり、「「安全でない」機能を確認してください」という意味です。「危険」は「危険」を意味するものではありません。

于 2013-03-02T09:31:56.127 に答える