Управление памятью в Excel

Область применения: Excel 2013 | Office 2013 | Visual Studio

Если вы хотите создавать эффективные и стабильные XLL-надстройки, особого внимания требует управление памятью. ������������ ���������� ������� ����� �������� � ������ ���� ������� � Microsoft Excel � �� ��������������, ����� ��� ��������� ������ ������ ��� �� ������������� ������������� � �������������, �� ���������, ����� ��� �������������� Excel.

������������ ���������� ������� � �������� ���������������� ������� ��������� �������, ��������� � ������������. �������������, ���������� ������ ������ ��� ������� ������ ����������� � ���������������� ��������� ���������� �������.

� ���������� �������������� ��������� ���� � Microsoft Office Excel 2007 ��������� ������� ����� �������. ���� �� ������ ��������� � �������������� ���������������� ������� ������, ���������� ��������� ���������, ������� ����� ��������� ��� ����������� ���������� ������� �� ������.

���� ��������� ������������ ��� ��������� ���� ����� ��������� ������:

  • XLOPERXLOPER12;
  • �����, ��������� ������� ���������� �� XLOPER ��� XLOPER12;
  • �������� FPFP12.

Память XLOPER и XLOPER12

Структура данных XLOPER/ XLOPER12 имеет несколько подтипов, которые содержат указатели на блоки памяти, а именно строки (xltypeStr), массивы (xltypeMulti) и внешние ссылки (xltypeRef). Note also that xltypeMulti arrays can contain string XLOPER/ XLOPER12s that in turn point to other blocks of memory.

An XLOPER/ XLOPER12 can be created in several ways:

  • � Excel ��� ���������� ���������� ��� �������� � ������� XLL;
  • � Excel ��� ����������� XLOPER ��� XLOPER12 �� ����� ������ API C;
  • � DLL ��� �������� ���������� ��� �������� �� ����� ������ API C;
  • в DLL при создании возвращаемого значения функции XLL.

Блок памяти, принадлежащий к типу указателей на память, можно выделить под что-то несколькими способами:

  • как статический блок в библиотеке DLL за пределами кода функции (в этом случае необязательно выделять или освобождать память);
  • ��� ����������� ���� � ���������� DLL, �������� � ��� ������� (� ���� ������ ������������� �������� ��� ����������� ������);
  • � ������� ������������� ��������� � ������������ � ���������� DLL ( mallocfree, newdelete � �. �.);
  • � ������� ������������� ��������� � Excel.

�������� ����� ��������� ���������� ������ XLOPER/ XLOPER12 � ���������� ��������, � ������� ���������� ������ XLOPER/ XLOPER12 ���������� ��� ������, �������������, ��� ��� ���� ����� ���� ����� �������. Тем не менее, если следовать нескольким правилам и рекомендациям, ее можно значительно упростить.

Правила работы с XLOPER/XLOPER12

  • Не пытайтесь освободить память или перезаписать XLOPER/ XLOPER12s, которые передаются в качестве аргументов функции XLL. Такие аргументы предназначены только для чтения. Дополнительные сведения см. в разделе Возвращение XLOPER или XLOPER12 путем изменения аргументов на месте статьи Известные проблемы в разработке XLL для Excel.

  • ���� ���������� Excel �������� ������ ��������� ������ XLOPER/ XLOPER12, ������������ � DLL �� ����� ������ API C:

    • ���������� ���������� ������, ����� ��� ������ �� ��������� XLOPER/ XLOPER12, � ������� ������ xlFree. �� ����������� ��� ����� ������ �����, �������� free ��� delete.
    • ���� ������������ ��� � xltypeMulti, �� ��������������� XLOPER/ XLOPER12 � �������, �������� ���� ��� �������� ������ ��� �� �������� ��������� ���������� � ������� ������.
    • ����� ���������� � Excel XLOPER/ XLOPER12 ��� ������������ �������� ������� DLL, ���������� �������� Excel � ������, ������� ���������� ���������� ����� ���������� ������.
  • ������� xlFree ���������� �������� ������ ��� ��������� ������ XLOPER/ XLOPER12, ��������� � �������� ������������� �������� ��� ������ API C.

  • ���� ���������� DLL �������� ������ ��������� ������ XLOPER/ XLOPER12, ������� ����� ���������� � Excel � �������� ������������� �������� ������� DLL, ���������� �������� Excel � ������, ������� ���������� DLL ������ ����������.

Рекомендации по управлению памятью

  • Используйте определенный метод для выделения и освобождения памяти в библиотеке DLL. Не смешивайте методы. ����������� ������������ ������ ����� ��� ��������� ��� ����� ������, ��� ��� ����� ��������, �� ������� ��� � ������ ������.
  • ��� �������� �������� xltypeMulti � ���������� DLL ��������� ������ ��� ����� ������������ ��������: ������ ��������� ������ ����������� ��� ������ ����������� ����������� ������. � ���� ������, ���������� ������, �� ������ �����, ��� ���������� ������ ����������� ������ ��� ������� ����� �� ������.
  • ���������� �������� ����� ���������� Excel ������ ��� ����������� ��������� � ������� Excel ��������� ������ XLOPER/ XLOPER12.
  • �� ��������� ���������� Excel ������ XLOPER/ XLOPER12 � ������� xltypeMulti. Создавайте глубокие копии строк и храните указатели на эти копии в массиве.

Освобождение выделенной Excel памяти XLOPER/XLOPER12

� ��������� ������� XLL ������������ ������� xlGetName ��� ��������� ������, ���������� ��� DLL-����� � ���� � ����, � ������� xlcAlert ��� �� ����������� � ���������� ���� ����������.

int WINAPI show_DLL_name(void)
{
    XLOPER12 xDllName;
    if(Excel12(xlfGetName, &xDllName, 0) == xlretSuccess)
    {
        // Display the name.
        Excel12(xlcAlert, 0, 1, &xDllName);
        // Free the memory that Excel allocated for the string.
        Excel12(xlFree, 0, 1, &xDllName);
    }
    return 1;
}

����� ������� ������ �� ����� ������, �� ������� ��������� xDllName, ��� ����� ���������� ��, ��������� ����� ������� xlFree, ����� �� ������� API C ������ ��� ��������� DLL.

������� xlFree �������� ������� � ����������� �� �������� (��. ������ ������� ���������� API ��� C, ������� ����� ���������� ������ �� DLL ��� XLL), �� �������� �������� �� ���������:

  • �� ������ ���������� ��������� ���������� ���������� ������ XLOPER/ XLOPER12 �� ����� ������ ������ ������� xlFree. ������������ ����������� ��� ���� � ���������� ���������� �������, ������� �������������� � ������������ ������ Excel (30 � Excel 2003, 255 � Excel�2007 � ����� ������� ������).
  • ������� xlFree ������������� ��� ������������� ��������� �������� NULL, ����� ���������� ������������ ��� ������� ������������ ��� ������������� ��������� ������ XLOPER/ XLOPER12. xlFree � ��� ������������ ������� API C, ������� �������� ���� ���������.
  • �� ������ ��������� �������� xlFree ��� ����� ��������� ������ XLOPER/ XLOPER12, ������� ������������ ��� ��������� ������������� �������� ��� ������ API C, ���������� �� ������� � ��� ��������� �� ������.

Возвращение структур данных XLOPER или XLOPER12 для освобождения в Excel

Предположим, вы хотите изменить пример команды в предыдущем разделе и изменить его на функцию листа, которая возвращает путь к DLL и имя файла при передаче логического аргументаtrue , а в противном случае #N/A . Clearly you cannot call xlFree to release the string memory before returning it to Excel. However, if it is not freed at some point, the add-in will leak memory every time the function is called. To work around this problem, you can set a bit in the xltype field of the XLOPER/ XLOPER12, defined as xlbitXLFree in xlcall.h. В результате Excel получит указание освобождать возвращаемую память после копирования выходного значения.

Пример

В следующем примере кода показано преобразование команды XLL из предыдущего раздела в функцию листа XLL.

LPXLOPER12 WINAPI get_DLL_name(int calculation_trigger)
{
    static XLOPER12 xRtnValue; // Not thread-safe
    Excel12(xlfGetName, &xRtnValue, 0);
// If xlfGetName failed, xRtnValue will be #VALUE!
    if(xRtnValue.xltype == xltypeStr)
    {
// Tell Excel to free the string memory after
// it has copied out the return value.
        xRtnValue.xltype |= xlbitXLFree;
    }
    return &xRtnValue;
}

������� XLL, ������� ���������� XLOPER/ XLOPER12, ���������� �������� ��� �����, ������� ��������� � ���������� ��������� �� XLOPER/ XLOPER12. ������������� � ���� ������� ����������� ������ XLOPER12 � ������� �� ���������������. �� ������ ����������� ���������������� ��� ������� ��� ����������������, �� ���������� ���� ���������� �������� xRtnValue ����� ������� �� ���������� ������ � ��� ������� ������.

�������� xlbitXLFree ���������� �������� ����� ������ ������� ��������� ������ Excel, ������� ��� ��������. ���� ������ ��� �� �����, ��� ����� ������������ � �� ���� ������� �������. ���� �� ������ ������������ ��� �������� � �������� ��������� �� ����� ������ ������ ������� API C �� ��� ����������� �� ����, ��� �������� ������� �������� ����� ������ ������. � ��������� ������ �� ����������� �������, ������� �� ��������� ��� �������� �� �������� ���� XLOPER/ XLLOPER12.

Возвращение структур данных XLOPER или XLOPER12 для освобождения в библиотеке DLL

����������� �������� ���������, ����� ���������� XLL �������� ������ XLOPER/ XLOPER12 � ����� ���������� �� � Excel. Excel ���������� ��� ���� ��������, ������� ����� ������ � ���� xltype ��������� ������ XLOPER/ XLOPER12, � xlbitDLLFree � xlcall.h.

Когда Excel получаетXLOPER12XLOPER/ с этим набором битов, он пытается вызвать функцию, которая должна быть экспортирована XLL с именем xlAutoFree (для XLOPERs) или xlAutoFree12 (для XLOPER12). Эта функция более подробно описана в справочнике по функциям (см. раздел Диспетчер надстроек и функции интерфейса XLL), но здесь приведен пример минимальной реализации. Его цель заключается в том, чтобы освободить память XLOPER12 XLOPER/ таким образом, чтобы она соответствовала первоначальному выделению.

Примеры

�������� ������� � ��������� ������� ���������� �������� ���������� ������� (�� ����������� ����, ��� ��� �������� ����� "The full pathname for this DLL is" ����� ������ DLL).

#include <string.h>
LPXLOPER12 WINAPI get_DLL_name_2(int calculation_trigger)
{
    static XLOPER12 xRtnValue; // Not thread-safe
    Excel12(xlfGetName, &xRtnValue, 0);
// If xlfGetName failed, xRtnValue will be #VALUE!
    if(xRtnValue.xltype != xltypeStr)
        return &xRtnValue;
// Make a copy of the DLL path and file name.
    wchar_t *leader = L"The full pathname for this DLL is ";
    size_t leader_len = wcslen(leader);
    size_t dllname_len = xRtnValue.val.str[0];
    size_t msg_len = leader_len + dllname_len;
    wchar_t *msg_text = (wchar_t *)malloc(msg_len + 1);
    wcsncpy_s(msg_text + 1, leader, leader_len);
    wcsncpy_s(msg_text + 1 + leader_len, xRtnValue.val.str + 1,
        dllname_len);
    msg_text[0] = msg_len;
// Now the original string has been copied Excel can free it.
    Excel12(xlFree, 0, 1, &xRtnValue);
// Now reuse the XLOPER12 for the new string.
    xRtnValue.val.str = msg_text;
// Tell Excel to call back into the DLL to free the string
// memory after it has copied out the return value.
    xRtnValue.xltype     = xltypeStr | xlbitDLLFree;
    return &xRtnValue;
}

����������� ���������� ������� xlAutoFree12 � ���������� XLL, ���������������� ���������� �������, �������� ��������� �������.

void WINAPI xlAutoFree12(LPXLOPER12 p_oper)
{
    if(p_oper->xltype == (xltypeStr | xlbitDLLFree))
        free(p_oper->val.str);
}

���� ���������� ����������, ������ ���� ���������� XLL ���������� ������ XLOPER12 � ��� ���������� � ������� ������� malloc. �������� ��������, ��� � ���� ������ ����

if(p_oper->xltype == xltypeStr)

���� ����, ��� ��� ������ �������� xlbitDLLFree.

� �����, ������� xlAutoFreexlAutoFree12 ���������� ����������� ���, ����� ��� ����������� ������, ��������� � ���������� ��� ������ XLL ��������� xltypeMulti � �������� �������� xltypeRef.

You might decide to implement your XLL functions so that they ALL return dynamically allocated XLOPERs and XLOPER12s. In this case, you would need to set xlbitDLLFree on all such XLOPERs and XLOPER12s regardless of the sub-type. You would also need to implement xlAutoFree and xlAutoFree12 so that this memory was freed and also any memory pointed to within the XLOPER/ XLOPER12. This approach is one way to make the return value thread safe. For example, the previous function could be rewritten as follows.

#include <string.h>
LPXLOPER12 WINAPI get_DLL_name_3(int calculation_trigger)
{
// Thread-safe
    LPXLOPER12 pxRtnValue = (LPXLOPER12)malloc(sizeof(XLOPER12));
    Excel12(xlfGetName, pxRtnValue, 0);
// If xlfGetName failed, pxRtnValue will be #VALUE!
    if(pxRtnValue->xltype != xltypeStr)
    {
// Even though an error type does not point to memory,
// Excel needs to pass this oper to xlAutoFree12 to
// free pxRtnValue itself.
        pxRtnValue->xltype |= xlbitDLLFree;
        return pxRtnValue;
    }
// Make a copy of the DLL path and file name.
    wchar_t *leader = L"The full pathname for this DLL is ";
    size_t leader_len = wcslen(leader);
    size_t dllname_len = pxRtnValue->val.str[0];
    size_t msg_len = leader_len + dllname_len;
    wchar_t *msg_text = (wchar_t *)malloc(msg_len + 1);
    wcsncpy_s(msg_text + 1, leader, leader_len);
    wcsncpy_s(msg_text + 1 + leader_len, pxRtnValue->val.str + 1,
        dllname_len);
    msg_text[0] = msg_len;
// Now the original string has been copied Excel can free it.
    Excel12(xlFree, 0, 1, pxRtnValue);
// Now reuse the XLOPER12 for the new string.
    pxRtnValue->val.str = msg_text;
    pxRtnValue->xltype = xltypeStr | xlbitDLLFree;
    return pxRtnValue;
}
void WINAPI xlAutoFree12(LPXLOPER12 p_oper)
{
    if(p_oper->xltype == (xltypeStr | xlbitDLLFree))
        free(p_oper->val.str);
    free(p_oper);
}

�������������� �������� � xlAutoFreexlAutoFree12 ��. � ������ xlAutoFree/xlAutoFree12.

Возвращение аргументов, изменяемых на месте

В Excel функция XLL может возвращать значение, изменяя аргумент на месте. Это возможно, только если аргумент передается в виде указателя. Для этого функцию необходимо зарегистрировать так, чтобы указать Excel, какой аргумент будет изменяться.

Этот метод для возвращения значения поддерживается для всех типов данных, которые можно передавать с помощью указателя, но особенно полезен для следующих типов:

  • ������ ������ ASCII, ��� ������� ������������ ������� ����� � ������� ������������ �����;
  • ������ ����������� �������� �������, ��� ������� ������������ ������� ����� � ������� ������������ ����� (� Excel�2007 � ����� ������� ������);
  • ������� FP � ��������� �������;
  • ������� � ��������� ������� FP12 (� Excel�2007 � ����� ������� ������).

Примечание.

Не следует пытаться возвращать таким образом XLOPER или XLOPER12. Дополнительные сведения см. в статье Известные проблемы, возникающие при разработке XLL для Excel.

������������ ����� ������� ��� �������������� ��������� ����������� ����������� � ���, ��� Excel �������� ������ ��� ������������ ��������. Завершив чтение возвращаемых данных, Excel освобождает память. Это освобождает функцию XLL от управления памятью. ���� ������ ���������������: ����� ������� � Excel ���������� ������������ � ��������� �������, ��� ������� ������ ������ ������������ ���� �����.

��� ������ ��� ������������� ����������� ���� ����� ������, ������ ��� �������� ��������� ������ DLL ��� ������������ ������ ����� �����������, ������� ���������� ��� XLOPER/ XLOPER12, �� ���������� ��� ������� ����� � �������� FP/ FP12. �������������, ��� ����������� ��������� � ������� DLL ������ ��� ������� � ��������� ������� � ��� ���� ����������� ���� ��������.

  • ���������� ���������� ��������� ��� ����������� ����������� ������, ���������� ���������. Во время следующего вызова функции (1) убедитесь, что значение указателя — не ноль, (2) освободите ресурсы, выделенные во время предыдущего вызова, и обнулите значение указателя, (3) повторно используйте указатель для нового выделенного блока памяти.
  • Создайте строки и массивы в статическом буфере, который не нужно освобождать, и возвратите указатель в него.
  • �������� ��������� �� �����, ������� ������ ��� ������ ��������������� � ������������, ���������� ����������� Excel.

Otherwise, you must create an XLOPER/ XLOPER12, and use xlbitDLLFree and xlAutoFree/ xlAutoFree12 to release the resources.

Последний вариант может быть самым простым в тех случаях, когда передается аргумент того же типа, что и возвращаемое значение. Важно помнить, что размер буфера ограничен, и вы должны быть очень осторожны, чтобы не переполнить их. Ошибка может привести к сбою Excel. Далее рассматриваются размеры буфера для строк и массивовFP12/ .

Строки

Проблемы с управлением памятью строк — наиболее распространенная причина нестабильной работы приложений и надстроек. Это понятно, учитывая множество различных типов строк и способов обработки. Есть строки, которые оканчиваются нулем или для которых используется счетчик длины (а еще строки, для которых выполняются оба эти условия); статические или динамические буферы; строки фиксированной длины или практически неограниченной длины; память, управляемая операционной системой (например, OLE Bstr), или неуправляемые строки, а также другие варианты.

������������ C/C++ ���� ����� ���������� ������, �������������� �����. Стандартная библиотека C предназначена для работы с такими строками. Статические строковые литералы в коде компилируются в строки, оканчивающиеся нулем. Кроме того, Excel работает со строками со счетчиком длины, которые обычно не оканчиваются нулем. Сочетание этих фактов требует четкого и последовательного подхода к обработке строк и памяти строк в DLL и XLL.

���� ��������� �������� ���������������� ��������.

  • �������� ������� ��� ������������� ��������� � �������, ������� ������� ���������� ��������� � �� ��������� ��� �� ����� ��������� ��� ������������.
  • ������������ ������ ������ ��������, ������� �� ������������ ��� �� ����� ����������� ������ ������ � ����� ������������ ������.
  • Попытка освободить память буфера строки, если он статический или уже освобожденный, а также если способы освобождения и выделения не совпадают.
  • Утечки памяти в результате выделения без последующего освобождения строк (обычно в часто вызываемой функции).

Правила для строк

��� � ��� XLOPER/ XLOPER, ��� ����� ���������� ������� � ������������, ������� ���������� ���������. ������������ �� ���������� �� ����������� � ���������� �������. Дополнительные правила для строк приведены ниже.

�������:

  • �� ��������� ���������� ������ ��� ������������ ������ XLOPER/ XLOPER12, � ����� ������� ������ �� ��������� ����� ��� ������, �������������� �����, ������� ���������� ��� ��������� � ������� XLL. ����� ��������� ������������� ������ ��� ������.
  • ���� Excel �������� ������ ������ XLOPER/ XLOPER12 ��� ��������� ������������� �������� ������� ��������� ������ API C, ���������� �� � ������� ������� xlFree ��� ������� �������� xlbitXLFree ��� �� ����������� � Excel �� ������� XLL.
  • Where your DLL dynamically allocates a string buffer for an XLOPER/ XLOPER12, free it in a way consistent with how you allocated it when done, or set xlbitDLLFree if returning it to Excel from an XLL function and then free it in xlAutoFree/ xlAutoFree12.
  • ���� Excel �������� ������ ������� xltypeMulti, ������������� � ���������� DLL �� ����� ������ API C, �� ��������������� ������ XLOPER/ XLOPER12 � �������. ��� ������������ ���� �������� ���������� ������������ ������ ������� xlFree ��� �������� xlbitXLFree ��� ����������� �� ������� XLL.

Поддерживаемые типы строк

������ XLOPER/XLOPER12 xltypeStr API C

Строки байтов: XLOPER Строки символов: XLOPER12
��� ������ Excel Excel�2007 � ����� ������� ������
������������ �����: 255 ������ ������������ ���� ASCII Максимальная длина: 32 767 символов Юникода
Первый байт (без знака) = длина Первый символ Юникода = длина

Важно!

[!�����!] ������ XLOPER ��� XLOPER12 �� ������ ������������ �����.

������ C/C++

������ ������ ������ ����������� ��������
Оканчивающиеся нулем (char *), тип "C", максимальная длина составляет 255 байтов расширенного кода ASCII Оканчивающиеся нулем (wchar_t *), тип "C%", максимальная длина составляет 32 767 символов Юникода
Со счетчиком длины (unsigned char *), тип "D" Со счетчиком длины (wchar_t *), тип "D%"

Строки в массивах XLOPER/XLOPER12 xltypeMulti

� ��������� ������� Excel ������� ������ xltypeMulti ��� ������������� � ����������� DLL � XLL. ��������� �������������� ������� XLM ���������� ����� �������. Например, функция API C xlfGetWorkspace при передаче ей аргумента 44 возвращает массив, содержащий строки, которые описывают все зарегистрированные процедуры DLL. ������� API C xlfDialogBox ���������� ���������� ����� ��������� �������, ���������� �������� ����� �����. ��������, ���� ����� ���������� XLL ������������ ������ xltypeMulti ��� ��� �������� � �������� ��������� � ������� XLL ��� �������������� � ���� ��� �� ���� ������ �� ��������. � ����� ������� Excel ������� �������� ����� ����� � �������� ������� � ��������� �� ��� � �������.

���� �� ������ �������� ��� ������ � ���������� DLL, ������� ������� ����������� �������� �����. ��� �������� ����������� �������� xltypeMulti �� ������� �������� � ��� ���������� Excel ������ XLOPER/ XLOPER12. ���������� ���� �� ���������� �� ��������� ��� �� ���������� ������. Кроме того, следует создавать глубокие копии строк и хранить указатели на копии в массиве.

�������

� ��������� ������� ������� ������� ����������� ���������� ����� ������ ������� �� ��������� �����. �������� ��������, ��� ���������� ������� � �������� ����� ������ ���������� ������, ���������� � ���� �������, � ������� ��������� delete[], � �������� ������ �� ������ ������������ �����. ������ ����� ���������, ���� ��� ���������� ��� ������������, � �� ������������ �����.

#include <string.h>
#define MAX_V12_STRBUFFLEN    32678
    
wchar_t * deep_copy_wcs(const wchar_t *p_source)
{
    if(!p_source)
        return NULL;
    size_t source_len = p_source[0];
    bool truncated = false;
    if(source_len >= MAX_V12_STRBUFFLEN)
    {
        source_len = MAX_V12_STRBUFFLEN - 1; // Truncate the copy
        truncated = true;
    }
    wchar_t *p_copy = new wchar_t[source_len + 1];
    wcsncpy_s(p_copy, p_source, source_len + 1);
    if(truncated)
        p_copy[0] = source_len;
    return p_copy;
}

����� � ������� ���� ������� ����� ��������� ���������� XLOPER12, ��� �������� �� ������� ��������� �������������� ������� XLL, ������������ ����� ���������, ���� ��� ������. ��� ������ ���� ������������ ��� ������ ������. �������� ��������, ��� ��������� �� �������������� � ������� ���������� #VALUE!. ��� ������� ���������� ���������������� ��� �����, ������� ��������� �������� ���� "U", ��� �������� ������ � ���� ��������. ��� ������������ ���������� ������� T() ����� (�� ����������� ����, ��� AsText ����� ����������� ������ � ������ ������). � ���� ������� ���� ��������������, ��� xlAutoFree12 ����������� ���������� ���������, � ����� ��� ����������, � ������� ��������� delete.

LPXLOPER12 WINAPI AsText(LPXLOPER12 pArg)
{
    LPXLOPER12 pRtnVal = new XLOPER12;
// If the input was an array, only operate on the top-left element.
    LPXLOPER *pTemp;
    if(pArg->xltype == xltypeMulti)
        pTemp = pArg->val.array.lparray;
    else
        pTemp = pArg;
    switch(pTemp->xltype)
    {
        case xltypeErr:
        case xltypeNum:
        case xltypeMissing:
        case xltypeNil:
        case xltypeBool:
            pRtnVal->xltype = xltypeStr | xlbitDLLFree;
            pRtnVal->val.str = deep_copy_wcs(L"\000");
            return pRtnVal;
        case xltypeStr:
            pRtnVal->xltype = xltypeStr | xlbitDLLFree;
            pRtnVal->val.str = deep_copy_wcs(pTemp->val.str);
            return pRtnVal;
        
        default: // xltypeSRef, xltypeRef, xltypeFlow, xltypeInt
            pRtnVal->xltype = xltypeErr | xlbitDLLFree;
            pRtnVal->val.err = xlerrValue;
            return pRtnVal;
    }
}

Возвращение строковых аргументов, изменяемых на месте

���������, ������������������ ��� ��������� ����� F, G, F%G%, ����� �������� �� �����. ������������� ��������� ��������� ��� ���� �����, Excel ������� ����� ������������� �������. Затем Excel копирует в него строку аргумента, даже если она значительно короче. Это позволяет функции XLL записывать возвращаемое значение непосредственно в ту же память.

Ниже приведены размеры буфера, установленные для этих типов.

  • Строки байтов: 256 байтов, включая счетчик длины (тип "G") или завершающий символ нуля (тип "F").
  • Строки в кодировке Юникод: 32 768 расширенных символов (65 536 байтов), включая счетчик длины (тип "G%") или завершающий символ нуля (тип "F%").

Примечание.

Эту функцию невозможно вызвать непосредственно из Visual Basic для приложений (VBA), так как вы не можете гарантировать выделение буфера достаточно большого размера. ��������� ��� ������� ����� ������� ������ �� ������ ���������� DLL, ���� �� ���� �������� ���������� ������� �����.

���� �������� ������ ������� XLL, ������� �������� �� �������� ������������������ ����������� �������� � ���������� ������, �������������� �����, ��������� ����������� ������� ���������� wcsrev. �������� � ���� ������ ����� ��������������� ��� �������� ���� F%.

void WINAPI reverse_text_xl12(wchar_t *text)
{
    _wcsrev(text);
}

Постоянное хранилище (двоичные имена)

Двоичные имена определяются и связаны с блоками двоичных, то есть неструктурированных данных, которые хранятся вместе с книгой. Они создаются с помощью функции xlDefineBinaryName, а данные извлекаются с помощью функции xlGetBinaryName. Обе функции более подробно описаны в справочнике по функциям (см. раздел Функции API C, которые могут вызываться только из БИБЛИОТЕКи DLL или XLL), и оба используют xltypeBigDataXLOPER/ XLOPER12.

�������� �� ��������� ���������, ������� ������������ ������������ ���������� �������� ����, ��. � ������ ��������� ��������, ����������� ��� ���������� XLL ��� Excel.

Стек Excel

Excel совместно использует пространство стека со всеми загруженными библиотеками DLL. Пространство в стеке обычно более чем достаточно для обычного использования, и вам не нужно беспокоиться об этом, если вы соблюдаете несколько рекомендаций:

  • �� ����������� ����� ������� ��������� � �������� ���������� ������� � ���� �������� � �����. ����������� ��������� ��� ������.
  • �� ����������� ������� ��������� � �����. ����������� ��������� �� ����������� ��� ����������� ���������� ������ ��� ����������� ���������, ������������ � �������������� ������.
  • �� ���������� ����� ������� ��������� �������������� ���������� � ���� �������. ���� ����������, �������� �� ��� �����������.
  • �� ��������� ������� ����������, ���� �� �������, ��� �������� ������ ����� ��������. ������ ����� ����������� ����.

������� �������� ����� �� ���������� DLL � ������� API C, Excel ������� ���������, ���������� �� ����� � ����� ��� ������ ������� ��������. ���� Excel ���������, ��� ���������� ����� ����� ���� ������������, �� ���������� ����� ��� ������������, ���� ���� �� ����� ���� ����� ����������. � ���� ������ ��� �������� ������ ������������ ��� xlretFailed. ��� ������� ������������� API C � ����� ���� ������ API C ���� �� ���������� �� ���� �������.

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

См. также

Многопоточный пересчет в Excel
��������������� � ��������� ������ � Excel
���������� XLL-������� ��� Excel 2013