简体   繁体   English

数组作为函数参数c到c#的混淆

[英]array as function parameter c to c# confusion

I am trying to write a class in C# to use exports from a dll but I have run into a bunch of functions that have an array as a function parameter that I am not sure how handle. 我试图用C#编写一个类,以使用dll的导出功能,但是我遇到了很多函数,这些函数具有数组作为函数参数,我不确定该如何处理。 Below is an example. 下面是一个例子。

How would I use this in function in C#? 我将如何在C#函数中使用它? Specifically how to handle iymdf[]? 具体如何处理iymdf []?

What is taking place when the function is called? 调用函数时会发生什么?

Does this seem correct? 这看起来正确吗?

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

example: 例:

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;
} 

function documentation: 功能文档:

/*
**  - - - - - - - - - -
**   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.
*/

Drop the ref keyword from the C# declaration, it isn't correct. 从C#声明中删除ref关键字,这是不正确的。 You also need to lose the initialization in the declaration, that's not supported syntax. 您还需要丢失声明中的初始化,这是不支持的语法。 Initialize the array before you make the call. 在进行调用之前初始化数组。

[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);

You'll be wanting a standard function call, depending on what you are doing. 您将要进行标准的函数调用,具体取决于您在做什么。 The function definition simply states "these are my inputs", then when you call it, you have to supply actual values. 函数定义仅声明“这些是我的输入”,然后在调用它时,必须提供实际值。 You don't recreate the function def. 您无需重新创建函数def。

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

Your function defines as returning an int, so we capture it with the myReturn variable, you'll need to declare it first of course. 您的函数定义为返回一个int,因此我们使用myReturn变量捕获它,您当然需要首先对其进行声明。 Then we supply an int, two doubles, and an array. 然后,我们提供一个int,两个double和一个数组。 You could also pass variables of those types, being careful to make sure your array is the same size as required. 您还可以传递这些类型的变量,请注意确保数组的大小与所需大小相同。

Also, watch your pointers! 另外,注意指针! If you pass a variable to c, it does a copy to the local variable defined in the function. 如果将变量传递给c,它将复制到函数中定义的局部变量。 If you give it a pointer, you need to declare it so in the function definition, and realize that we are now playing the pointer game. 如果给它一个指针,则需要在函数定义中声明它,并意识到我们正在玩指针游戏。

Too answer my own question, I thought there would be more Marshaling stuff involved, but the below code gives a reasonable output. 太回答我自己的问题了,我认为会涉及到更多的Marshaling东西,但是下面的代码给出了一个合理的输出。

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

as well as this: 以及这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM