массив как параметр функции c к c # путаница - PullRequest
2 голосов
/ 27 апреля 2011

Я пытаюсь написать класс на C #, чтобы использовать экспорт из DLL, но я столкнулся с набором функций, которые имеют массив в качестве параметра функции, который я не уверен, как обрабатывать.Ниже приведен пример.

Как бы я использовал это в функции в 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.
*/

Ответы [ 3 ]

4 голосов
/ 27 апреля 2011

Удалите ключевое слово ref из объявления 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);
1 голос
/ 27 апреля 2011

Вам потребуется стандартный вызов функции, в зависимости от того, что вы делаете.Определение функции просто гласит «это мои входные данные», а затем, когда вы ее вызываете, вы должны указать фактические значения.Вы не воссоздаете функцию def.

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

Ваша функция определяет как возвращающую int, поэтому мы фиксируем ее с помощью переменной myReturn, вам, конечно, нужно сначала объявить ее.Затем мы поставляем int, два типа double и массив.Вы также можете передавать переменные этих типов, следя за тем, чтобы размер вашего массива соответствовал требуемому.

Также следите за указателями!Если вы передадите переменную в c, она скопирует локальную переменную, определенную в функции.Если вы дадите ему указатель, вам нужно объявить его в определении функции и понять, что мы сейчас играем в игру с указателем.

0 голосов
/ 27 апреля 2011

Слишком ответь на мой собственный вопрос, я думал, что там будет больше маршалинга, но код ниже дает разумный вывод.

    [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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...