2011-04-26 78 views
2

我想在C#中编写一个类来使用dll的导出,但我遇到了 一堆函数,它有一个数组作为函数参数,我不确定 如何处理。下面是一个例子。数组作为函数参数c到c#混淆

我该如何在C#中的函数中使用它?具体如何处理iymdf []?

函数调用时发生了什么?

这是否正确?

[DllImport("libsofa.dll")] 
public static extern int iauJdcalf(int ndp, double dj1, double dj2, ref int[] iymdf =  new int[4]); 

例如:

int __stdcall iauJdcalf(int ndp, double dj1, double dj2, int iymdf[4]) 
{ 
    int j, js; 
    double denom, d1, d2, f1, f2, f; 

    /* Denominator of fraction (e.g. 100 for 2 decimal places). */ 
    if ((ndp >= 0) && (ndp <= 9)) { 
     j = 0; 
     denom = pow(10.0, ndp); 
    } else { 
     j = 1; 
     denom = 1.0; 
    } 

    /* Copy the date, big then small, and realign to midnight. */ 
    if (dj1 >= dj2) { 
     d1 = dj1; 
     d2 = dj2; 
    } else { 
     d1 = dj2; 
     d2 = dj1; 
    } 
    d2 -= 0.5; 

    /* Separate days and fractions. */ 
    f1 = fmod(d1, 1.0); 
    f2 = fmod(d2, 1.0); 
    d1 = floor(d1 - f1); 
    d2 = floor(d2 - f2); 

    /* Round the total fraction to the specified number of places. */ 
    f = floor((f1+f2)*denom + 0.5)/denom; 

    /* Re-assemble the rounded date and re-align to noon. */ 
    d2 += f + 0.5; 

    /* Convert to Gregorian calendar. */ 
    js = iauJd2cal(d1, d2, &iymdf[0], &iymdf[1], &iymdf[2], &f); 
    if (js == 0) { 
     iymdf[3] = (int) (f * denom); 
    } else { 
     j = js; 
    } 

    /* Return the status. */ 
    return j; 
} 

函数文档:

/* 
** - - - - - - - - - - 
** i a u J d c a l f 
** - - - - - - - - - - 
** 
** Julian Date to Gregorian Calendar, expressed in a form convenient 
** for formatting messages: rounded to a specified precision. 
** 
** This function is part of the International Astronomical Union's 
** SOFA (Standards Of Fundamental Astronomy) software collection. 
** 
** Status: support function. 
** 
** Given: 
**  ndp  int  number of decimal places of days in fraction 
**  dj1,dj2 double dj1+dj2 = Julian Date (Note 1) 
** 
** Returned: 
**  iymdf  int[4] year, month, day, fraction in Gregorian 
**      calendar 
** 
** Returned (function value): 
**    int  status: 
**       -1 = date out of range 
**       0 = OK 
**       +1 = NDP not 0-9 (interpreted as 0) 
** 
** Notes: 
** 
** 1) The Julian Date is apportioned in any convenient way between 
**  the arguments dj1 and dj2. For example, JD=2450123.7 could 
**  be expressed in any of these ways, among others: 
** 
**    dj1   dj2 
** 
**   2450123.7   0.0  (JD method) 
**   2451545.0  -1421.3  (J2000 method) 
**   2400000.5  50123.2  (MJD method) 
**   2450123.5   0.2  (date & time method) 
** 
** 2) In early eras the conversion is from the "Proleptic Gregorian 
**  Calendar"; no account is taken of the date(s) of adoption of 
**  the Gregorian Calendar, nor is the AD/BC numbering convention 
**  observed. 
** 
** 3) Refer to the function iauJd2cal. 
** 
** 4) NDP should be 4 or less if internal overflows are to be 
**  avoided on machines which use 16-bit integers. 
** 
** Called: 
**  iauJd2cal JD to Gregorian calendar 
** 
** Reference: 
** 
**  Explanatory Supplement to the Astronomical Almanac, 
**  P. Kenneth Seidelmann (ed), University Science Books (1992), 
**  Section 12.92 (p604). 
** 
** This revision: 2010 July 27 
** 
** SOFA release 2010-12-01 
** 
** Copyright (C) 2010 IAU SOFA Board. See notes at end. 
*/ 
+0

您应该再次阅读许可证并更改您的代码。你不符合你的要求。我正在尝试使用Ruby来完成与所有C SOFA代码类似的构建。 – 2014-04-01 23:28:07

回答

1

你会想要一个标准的函数调用,这取决于你在做什么。函数定义只是声明“这些是我的输入”,然后当您调用它时,必须提供实际值。你不重新创建函数def。

[DllImport("libsofa.dll")] 
myReturn = iauJdcalf(1, 2.0, 2.0, [1,2,3,4]); 

你的函数定义为返回一个int,所以我们用myReturn变量捕获它,你需要首先声明它。然后我们提供一个int,两个double和一个数组。你也可以传递这些类型的变量,注意确保你的数组的大小与需要的相同。

另外,看你的指针!如果你将一个变量传递给c,它将复制到函数中定义的局部变量。如果你给它一个指针,你需要在函数定义中声明它,并且意识到我们现在正在玩指针游戏。

0

为了回答我自己的问题,我认为会有更多涉及Marshaling的东西,但下面的代码 提供了合理的输出。

[DllImport("libsofa.dll")] 
    public static extern int iauJdcalf(int ndp, double dj1, double dj2, [MarshalAs(UnmanagedType.LPArray, SizeConst = 4)] int[] iymdf); 

以及本:

[DllImport("libsofa.dll")] 
    public static extern int iauJdcalf(int ndp, double dj1, double dj2, int[] iymdf); 
+1

这不是一个答案。而不是你的用户帐户,看它的外观。 – 2011-04-27 00:46:37

4

删除从C#声明裁判关键字,这是不正确的。您还需要失去声明中的初始化,这不是受支持的语法。在进行呼叫之前初始化数组。

[DllImport("libsofa.dll")] 
public static extern int iauJdcalf(int ndp, double dj1, double dj2, int[] iymdf); 
... 
    int[] arr = new int[] { 1, 2, 3, 4 }; 
    int retval = iauJdcalf(1, 2, 3, arr);