Возврат двумерного массива в excel из c++ xll, возврат

Прежде всего, я знаю, что вопрос уже задавался здесь:

вернуть многомерный массив в excel из c++ xll

Я пытался оживить тему, но безуспешно. (ОП не был таким активным в последнее время, никогда не был.) Вот почему я снова задаю вопрос, заранее извините.

Я закодировал функцию, возвращающую (строку) одномерный массив:

__declspec(dllexport) LPXLOPER12 WINAPI Get1DArray(void)
{
    static XLOPER12 xlArray;
    XLOPER12 xlValues[2];
    xlValues[0].xltype = xltypeNum;
    xlValues[1].xltype = xltypeNum;
    xlValues[0].val.num = 123;
    xlValues[1].val.num = 456;
    xlArray.xltype = xltypeMulti | xlbitDLLFree;
    xlArray.val.array.rows = 1;
    xlArray.val.array.columns = 2;
    xlArray.val.array.lparray = &xlValues[0];
    return static_cast<LPXLOPER12>(&xlArray);
}

это работает. Я пробовал то же самое, что и ОП из вопроса, о котором я упоминал выше, пытался (вот как я наткнулся на его вопрос).

Единственный документ, который у меня есть, это msdn для excel sdk, он мне не помог. Функция, которую я закодировал, я использовал пример, найденный в Интернете. Не нашел ни одного для двумерного массива. Знаю книги Стива Далтона про xll, не помогли.

Я подозреваю, что многомерные массивы XLOPER12 хранят значения в одномерных массивах, нумеруя по строкам и столбцам или столбцам и строкам, но не удалось использовать эту интуицию...

Вот почему я здесь.


person Olorin    schedule 12.04.2017    source источник


Ответы (1)


Простой пример, возвращающий матрицу 5*5. Не забудьте освободить выделенный массив с помощью функции xlAutoFree12.

__declspec(dllexport) LPXLOPER12 WINAPI Get2DArray(void)
{   
    static XLOPER12 xlArray;
    int rows = 5;
    int cols = 5;
    xlArray.xltype = xltypeMulti | xlbitDLLFree;
    xlArray.val.array.rows = rows;
    xlArray.val.array.columns = cols;
    xlArray.val.array.lparray = reinterpret_cast<LPXLOPER12>(::malloc(rows * cols * sizeof(XLOPER12)));
    for (int r=0;r<rows;r++)
    {
            for (int c=0;c<cols;c++)
            {
                XLOPER12* var = xlArray.val.array.lparray + ((r* cols) + c);
                var->xltype = xltypeNum;
                var->val.num = r*c;
            }
    }
    return &xlArray;
}
person Malick    schedule 13.04.2017
comment
Что вы подразумеваете под освобождением выделенного массива с помощью функции xlAutoFree12? ... - person Olorin; 13.04.2017
comment
val.array.lparray выделяется в куче (мы используем malloc), поэтому вы должны освободить его с помощью ::free(reinterpret_cast<void*>(val.array.lparray)); внутри xlAutoFree12 , см. msdn.microsoft.com/en-us/library/bb687922(v=office.15).aspx. Excel скопирует содержимое массива и вернет массив в dll через xlAutoFree12, чтобы dll могла освободить ту часть кучи, которая была выделена dll и которую Excel не может освободить. Чтобы узнать больше об этом, прочитайте главу об управлении памятью в книге Далтона. - person Malick; 13.04.2017
comment
Хорошо, спасибо. Последний пункт, почему reinterpret_cast? Почему static_cast возвращается? - person Olorin; 13.04.2017
comment
malloc возвращает указатель void, поэтому вам нужно переинтерпретировать его, чтобы сохранить его в lparray. Что касается static_cast , извините, это ошибка, я только что удалил ее. - person Malick; 13.04.2017
comment
Ах хорошо, спасибо! Последний пункт: буду ли я кодировать функцию, принимающую матрицу, изменяющую ее и возвращающую ее, будет ли тип параметра функции по-прежнему LPXLOPER12 ? - person Olorin; 13.04.2017
comment
Да, LPXLOPER12 может возвращать любую переменную (матрицу, строку, число...) - person Malick; 13.04.2017
comment
Это я понял, мой вопрос о наличии параметра, который является матрицей - person Olorin; 13.04.2017
comment
Да то же самое для входных переменных. - person Malick; 13.04.2017
comment
Я попробовал arrayin->val.array.lparray + ((r* cols) + c))->xltype == xltypeNum, где LPXLOPER12 arrayin — мой входной параметр, и произошел сбой. Я беру матрицу 5 * 5 из Excel, при отладке я вижу, что она имеет 19 строк и 20 столбцов, с!? Может быть, это потому, что когда я получаю LPXLOPER12 arrayin, он представляет собой диапазон, намного более сложный, чем матрица 5 * 5. Как тогда получить доступ к матрице 5 * 5, которую она содержит? - person Olorin; 13.04.2017
comment
Если у вас есть другой вопрос, отправьте его. Это поможет другим пользователям, комментарии не предназначены для расширенных обсуждений, и я считаю, что ответил на ваш первоначальный вопрос. - person Malick; 13.04.2017
comment
И увеличивайте счетчик ответов, но ладно, это действительно лучшая практика ;-) - person Olorin; 13.04.2017
comment
Вот: stackoverflow.com/questions/43397349/ - person Olorin; 13.04.2017