2011-06-03 94 views
4

我可以將C#結構傳遞給FORTRAN就好了。我甚至可以將C#結構的數組作爲TYPE()的數組傳遞給FORTRAN。我遇到麻煩的地方是當我試圖將值返回到C#時。下面是一個例子:從C#調用FORTRAN DLL並將值分配給結構數組

的FORTRAN DLL是:一個期望結果

MODULE TESTING 

    TYPE VALUEREF 
    INTEGER*4 :: A 
    ENDTYPE VALUEREF 

CONTAINS 

    SUBROUTINE TEST_REF(T,N) 
    !DEC$ ATTRIBUTES DLLEXPORT :: TEST_REF 
    !DEC$ ATTRIBUTES ALIAS:'TEST_REF' :: TEST_REF 
    !DEC$ ATTRIBUTES VALUE :: N 
    IMPLICIT NONE 
    INTEGER*4 :: A,I,N 
    TYPE(VALUEREF) :: T(N)  
    A = 100 
    DO I=1,N 
     T(I)%A = A + I 
    END DO 

    END SUBROUTINE 
END MODULE 

C#調用函數是:

[StructLayout(LayoutKind.Sequential)] 
public struct ValueRef 
{ 
    public int a; 
} 

[DllImport("mathlib.dll")] 
static extern void TEST_REF(ValueRef[] t, int n); 

void Main() 
{ 
    ValueRef[] T = new ValueRef[4]; 
    for (int i = 0; i < T.Length; i++) 
    { 
     T[i].a = i; 
    } 
    Console.WriteLine("Initialize"); 
    for (int i = 0; i < T.Length; i++) 
    { 
     Console.WriteLine(" A={0}", T[i].a); 
    } 
    Console.WriteLine("Call Fortran"); 
    TEST_REF(T, T.Length); 
    for (int i = 0; i < T.Length; i++) 
    { 
     Console.WriteLine(" A={0}", T[i].a); 
    } 
} 

帶結果:

Initialize 
    A=0 
    A=1 
    A=2 
    A=3 
Call Fortran 
    A=0 
    A=1 
    A=2 
    A=3 

調試通過FORTRAN代碼,我看到初始值從C#傳遞到FORTRAN就好。這些值將被新值覆蓋,並且控制權將傳回到C#,其中舊值仍包含在ValueRef實例中。

爲什麼我可以通過並以類似的方式返回一組floatint,這很好。我可以通過並返回單數結構與ref關鍵字,我可以通過,但返回和struct數組?

PS。我正在使用Compaq Visual Fortran 6.5 & .NET 3.5
PS2。我很欣賞這方面的任何意見/想法。我完成了95%的項目,現在我遇到了這個問題。這個項目的重點是儘可能地使用結構來減少傳遞給函數的#參數,並保留OOP設計的某些方面。

+1

我想這取決於運行時如何編組你的值,這應該不是問題,它總是工作正常,我很驚訝地看到一個FORTRAN/C#混合。 – 2011-06-03 19:45:58

+0

注意反標格式不可用於標題,不幸的是 – AakashM 2011-06-03 21:12:59

+1

現實中的現代FORTRAN很容易和快速。我沒有理由不僅爲了保留遺留代碼,而且在FORTRAN中開發新代碼。當然對於GUI而言,我將它留給C#/ OpenTK。 – ja72 2011-06-04 03:30:07

回答

4

我已經在過去使用指針而不是數組完成了這項工作。我認爲您的結構正在被複製爲P/Invoke調用:

[DllImport("mathlib.dll")] 
static extern void TEST_REF(ValueRef* t, int n); 

您將需要在調用方法之前固定您的數組。

fixed (ValueRef* pointer = t) 
{ 
    TEST_REF(pointer, n); 
} 

編輯: 基於註釋的解決方案是聲明外部的

[DllImport("mathlib.dll")] 
static extern void TEST_REF([Out] ValueRef[] t, int n); 

這裏是一個MSDN參考陣列的封送處理,和他們默認[In]如何。

+0

我剛纔建議......確保你用不安全的標誌編譯你的代碼,並用unsafe關鍵字標記你的方法和範圍,否則你會得到一堆編譯錯誤。 – 2011-06-03 19:47:49

+0

當我傳遞一個單一的結構byref然後它不被複制,但是當我傳遞一個數組時,它被複制!? – ja72 2011-06-04 02:41:07

+1

您可以嘗試的第二件事是使用P/Invoke簽名中的[Out]屬性。 – 2011-06-05 08:10:43