Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,472

Не работают функции 64 бит библиотеки в надстройке Эксель 2013

23.05.2016, 14:38. Показов 3340. Ответов 42
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Имеется DLL: одна для 32 бит и одна для 64 бит
h-файл
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//------------------------------------------------------------------------------
#ifndef X_H
#define X_H
//------------------------------------------------------------------------------
#include <windows.h>
//------------------------------------------------------------------------------
#ifdef EXPORT
#define DECL_SPEC __stdcall __declspec(dllexport)
#else
#define DECL_SPEC __stdcall __declspec(dllimport)
#endif
 
#ifdef __cplusplus
extern "C" {
#endif
//------------------------------------------------------------------------------
double DECL_SPEC x_x(double T);
//------------------------------------------------------------------------------
#ifdef __cplusplus
} //extern "C"
#endif
 
#undef EXPORT
//------------------------------------------------------------------------------
#endif //X_H

cpp-файл
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#define EXPORT
#include "x.h"
 
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    switch (reason)
    {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return 1;
}
 
double DECL_SPEC x_x(double T)
{
    return T * T;
}

сборка для 64 бит в MinGW64
Кликните здесь для просмотра всего текста
f:\mingw64\bin\g++ -mdll -Wl,--kill-at x.cpp -o x.dll

имеется надстройка Excel
Кликните здесь для просмотра всего текста
Visual Basic
1
2
3
4
5
#If VBA7 Then
Public Declare PtrSafe Function x_x Lib "x.dll" (ByVal T As Double) As Double
#Else
Public Declare Function x_x Lib "x.dll" (ByVal T As Double) As Double
#End If

в версиях 32 бит все работает как надо. в Excel 2010 64 бит все так же нормально. в Excel 2013 64 бит вызов функции x_x вне зависимости от аргумента возвращает ноль. причина?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.05.2016, 14:38
Ответы с готовыми решениями:

Пустая закладка в надстройке Outlook 2013
Всем доброго времени суток. Исходные данные: 1. VS2013 prof. 2. Outlook 2013 add in. Создал надстройку , в ribbon создал...

При открытии файла .csv в эксель 2013 в некоторых клетках дата вместе числа
работаю с базами таможни, импортирую csv файлы на несколько десятков тысяч строк и около сотни колонн. очень часто замечаю, что даты...

Регистрация библиотеки в реестр 64 бит
Начал немного знакомиться с COM. Нашел статью в интернете http://www.rsdn.ru/article/com/introcom.xml. Все делаю как там написано, создал...

42
 Аватар для HighPredator
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
16.06.2016, 11:45
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Убежденный Посмотреть сообщение
sizeof (long double) в GCC выдает 12, а в MSVC - 8
Так МС же забили поддерживать 80-битный лонг дабл и свели репрезентативность к обычному.
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
16.06.2016, 11:46
Цитата Сообщение от Убежденный Посмотреть сообщение
sizeof (long double) в GCC выдает 12, а в MSVC - 8
Я понял, что имеется в виду, но считаю это маловероятным.

Добавлено через 53 секунды
Цитата Сообщение от HighPredator Посмотреть сообщение
Так МС же забили поддерживать 80-битный лонг дабл
А чем объяснили?
0
 Аватар для HighPredator
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
16.06.2016, 11:52
Цитата Сообщение от nmcf Посмотреть сообщение
А чем объяснили?
Если я правильно понял инфу, то это связано с тем, что они переводили генерацию кода математического сопроцессора на sse инструкции, а не на какой-то x87 стек. А на sse поддерживаются только 32 и 64 битные форматы действительных чисел.
2
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,472
16.06.2016, 13:59  [ТС]
Убежденный, HighPredator, итак, в функцию в самое начало был добавлен код
C++
1
2
    char *p = 0;
    char c = *p;
приводящий к завершению работы Excel при вызове. после ввода в ячейку =x_x(10) и выдачи сообщения о завершении работы был снят дамп при помощи procdump64. ссылка на дамп и полный проект прилагаются. помогите люди добрые
Вложения
Тип файла: rar test.rar (231.8 Кб, 4 просмотров)
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
16.06.2016, 23:32
Лучший ответ Сообщение было отмечено BANO как решение

Решение

Уф, пришлось попотеть (как человеку, который никогда не программировал на VBA и
пользуется MS Office раз в полгода для задач класса "письмо написать").


Ковыряние в дампе и запуск Excel под отладчиком ничего не дало.
Я даже не мог из VBA нормально вызвать MessageBox, ни на Excel 2010, ни на Excel 2013,
вместо аргументов передавалась какая-то ерунда. А разгадка нашлась здесь:

How to: Access DLLs in Excel
https://msdn.microsoft.com/en-... 2147217396
Calling DLL Functions Directly from the Worksheet

You cannot access Win32 DLL functions from the worksheet without, for example, using VBA or
XLM as interfaces, or without letting Excel know about the function, its arguments, and
its return type in advance. The process of doing this is called registration.

The ways in which the functions of a DLL can be accessed in the worksheet are as follows:

* Declare the function in VBA as described previously and access it via a VBA user-defined function.

* Call the DLL function using CALL on an XLM macro sheet, and access it via an XLM user-defined function.

* Use an XLM or VBA command to call the XLM REGISTER function, which provides the information
that Excel needs to recognize the function when it is entered into a worksheet cell.

* Turn the DLL into an XLL and register the function using the C API xlfRegister function when the XLL is activated.
Я пошел по самому легкому пути - "Declare the function in VBA and access it via a VBA
user-defined function". Заработало так (проверил на Excel 2010 и на Excel 2013, оба 64-битные):
Visual Basic
1
2
3
4
5
Private Declare PtrSafe Function x_x Lib "C:\Lib\x.dll" (ByVal T As Double) As Double
 
Function MyWrapper(ByVal T As Double) As Double
    MyWrapper = x_x(T)
End Function
В ячейку надо вводить '=MyWrapper(10)', а не '=x_x(10)'.
3
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,472
17.06.2016, 10:03  [ТС]
Убежденный, через обертку работает, Спасибо! пока это единственный реально работающий способ, люди влепите кто-нибудь "лучший ответ", а то движок нашего форума не дает мне это сделать видимо от того что я поставил отзыв на пост.
----
любопытные факты:
1) вызов функций DLL декларированных в модуле надстройки Excel прямо с листа книги Excel работает на всех 32 битных версиях и на 64 битных версиях до 2010 включительно - только Excel 2013 64 бит по каким-то причинам что-то изменил в порядке вызова функций: Excel видит функции, вызывает их и получает от них КОРРЕКТНЫЙ результат, но не может корректно передать им параметры - интересно какого лешего они там сделали и все переломали по сравнению с предыдущими версиями которые работали на протяжении 20 лет???
2) как уже сказано - удивительно, что Excel 2013 64 бит передав в функцию некорректные параметры умудряется получить КОРРЕКТНЫЙ результат (!!!) - я возвращал из функций вместо результата вычислений просто число 123 и для double и для DWORD (причем ради чистоты эксперимента параметры продолжали передаваться в функцию) - на листе книги Excel при вызове выдается АБСОЛЮТНО корректные 123. то есть если я правильно понимаю ситуацию вызов происходит правильно - краш от неправильной очистки стека не происходит или мы просто не замечаем этого так как это не критично из-за стратегии применяемой Excel при вызове
3) что же заставляет Excel передавать неверные и МЕНЯЮЩИЕСЯ параметры в функцию??? вот какую любопытную фразу я нашел тут и пока еще осмысливаю
On ARM and x64 processors, __stdcall is accepted and ignored by the compiler; on ARM and x64 architectures, by convention, arguments are passed in registers when possible, and subsequent arguments are passed on the stack.
то есть не исключено что со стороны Excel часть параметров идет через регистры не смотря на соглашение в то время как DLL об этом даже не догадывается и вычитывает из стека мусор еще в добавок очищая его при возврате

Добавлено через 7 минут
4) возврат результата наверное идет корректно потому что возвращается POD через EAX и в этом мнение DLL и Excel совпадают
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
17.06.2016, 10:08
vxg, в Win64 первые четыре аргумента всегда передаются через регистры -
RCX, RDX, R8, R9, а в случае с double, как в нашем примере, используется XMM0 (SSE).
Но, как я понял из игр с отладчиком, 64-битный Excel не передает параметры корректно,
если для функции не была сделана "регистрация" (registration, см. выше).
Там и в стеке, и в регистрах в момент вызова получается полная каша.
Когда я поменял Double на Long, то мне вдруг стал приходить правильный аргумент в XMM0.
В других случаях правильный аргумент оказывался в регистре RBX. В случае с MessageBox
аргументы словно "сдвинулись" на один влево. И т.д. И только при вызове через враппер
все стало нормально. Причем у меня это поведение наблюдалось и на Office 2010.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,472
17.06.2016, 10:33  [ТС]
Убежденный, странно... я отлаживал DLL на Excel 2010 64 бит и у человека который прислал мне отчет об ошибке тоже все корректно работает на Excel 2010 64 бит без оберток...

Добавлено через 1 минуту
Убежденный, а может быть так как я написал? что Excel как-то по своему неожиданно для DLL передает параметры? вот, пытаюсь найти ключики управляющие передачей в g++

Добавлено через 35 секунд
...может за волшебство отвечает студия? если в ней собрать DLL они сразу друг друга поймут)?

Добавлено через 1 минуту
...просто этому обязано быть объяснение. то что обертка работает - это да, но все таки мне кажется каким то хаком. должна быть причина аномалии

Добавлено через 51 секунду
...оборачивать каждый раз функцию что бы вызвать с листа это графоманский идиотизм какой то

Добавлено через 12 минут
Цитата Сообщение от Убежденный Посмотреть сообщение
В случае с MessageBox
аргументы словно "сдвинулись" на один влево
там возможно не были изменены типы в списке аргументов - в 64 битной версии типы которым в C++ соответствует Handle по другому обзываются

Добавлено через 2 минуты
что то такое
Handles and pointers need to be converted to LongPtr.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
17.06.2016, 10:59
Цитата Сообщение от vxg Посмотреть сообщение
странно... я отлаживал DLL на Excel 2010 64 бит и у человека который прислал мне отчет об ошибке тоже все корректно работает на Excel 2010 64 бит без оберток...
Наверное, версия Office тоже имеет значение.
У меня была Office 2010 Professional Plus SP2, какой-то репак с торрента,
подлинность версии под вопросом, но это все, что было под рукой.

а может быть так как я написал? что Excel как-то по своему неожиданно для DLL передает параметры? вот, пытаюсь найти ключики управляющие передачей в g++
Если бы Excel отошел от конвенции, из него вообще никакие функции нельзя
было вызывать, даже WinAPI-шные.

может за волшебство отвечает студия? если в ней собрать DLL они сразу друг друга поймут)?
Я пробовал собирать x.dll в Visual Studio - картина принципиально не изменилась.
И ассемблерный код функции x_x смотрел: и в случае GCC, и в случае MSVC, там все корректно.

просто этому обязано быть объяснение. то что обертка работает - это да, но все таки мне кажется каким то хаком. должна быть причина аномалии
А обязательно нужна причина?
На MSDN написано "cannot", значит все, дальше копать не рационально.

оборачивать каждый раз функцию что бы вызвать с листа это графоманский идиотизм какой то
Согласен.
Но ведь кроме VBA-обертки, есть и другие варианты. Я, правда, в них не разбирался.

там возможно не были изменены типы в списке аргументов - в 64 битной версии типы которым в C++ соответствует Handle по другому обзываются
Я пробовал и Long, и LongPtr - все то же самое.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,472
17.06.2016, 12:17  [ТС]
Убежденный
покопал тему нашел такие вот печальки:
тут человек столкнулся с этой проблемой в Excel 2010 и не долго думая решил ее через оборачивание
тут человек столкнулся с этой проблемой в Excel 2013, написал в MS и получил ответ - миграция на XLL - причем ответили ему одно и то же два раза как попугаи
тут мой крик о проблеме ибо проблема есть и она не решена)
пусть хоть скажут П О Ч Е М У ?

Добавлено через 2 минуты
Цитата Сообщение от Убежденный Посмотреть сообщение
На MSDN написано "cannot"
может это сложности перевода) я например ту фразу могу прочитать как "вы не можете вызвать функцию с листа Excel напрямую без ДЕКЛАРАЦИИ ее в модуле VBA что я и делаю)"

Добавлено через 39 секунд
...там много чего написано в том числе в разных местах например указывается разный размер типов))

Добавлено через 1 минуту
Цитата Сообщение от Убежденный Посмотреть сообщение
кроме VBA-обертки, есть и другие варианты
пробовал вызывать регистрацию в Auto_Open - то ли я что то ей не так даю то ли еще что то но Excel вообще перестает видеть функцию

Добавлено через 40 секунд
...XLL не хочу использовать так как это хранение специфичного хлама в общей DLL
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,472
21.06.2016, 15:20  [ТС]
вот что мне ответили эти г@ндоны
Since the issue is complex, I suggest you contacting Microsoft support to raise an incident so that our engineer could work closely with him to identify the root cause and resolve this issue as soon as possible.
If the support engineer determines that the issue is the result of a bug the service request will be a no-charge case and you won't be charged.
Please visit the below link to see the various paid support options that are available to better meet your needs.
0
21.06.2016, 15:24

Не по теме:

Не ну в принципе ожидаемый ответ..

0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,472
21.06.2016, 15:26  [ТС]
HighPredator, честно говоря ожидал что меня пошлют чуть более романтично. что-нибудь вроде: спасибо за ваш отчет об ошибках! наши инженеры работают над устранением проблемы. как только решение будет найдено мы обязательно сообщим вам! согласитесь - это вызывает меньше бешенства при той же смысловой нагрузке в виде "отвалите"
0
 Аватар для HighPredator
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
21.06.2016, 15:32
vxg, я не очень внимательно изучил детали ответа, но у меня сложилось впечатление, что вам ответил не представитель их QA, а кто-то из верхов коммьюнити. Поэтому вроде как он и не должен расшаркиваться.

Добавлено через 1 минуту
Посмотрел. Действительно это не сотрудник мс, а просто аффилированое лицо.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,472
21.06.2016, 15:38  [ТС]
Цитата Сообщение от HighPredator Посмотреть сообщение
аффилированое лицо.
я в их иерархию не вдавался но у меня сложилось впечатления что там народ просто своими ответами себе карму делает наподобие как у нас на форуме. возможно у них эти спасибки или просто количество "бла бла бла" еще как то засчитываются за стаж консультации если человек в штатных попугаях состоит
0
 Аватар для HighPredator
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
21.06.2016, 15:42
vxg, все может быть.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,472
22.06.2016, 10:25  [ТС]
Убежденный, HighPredator, еще одна шарада из той же оперы:
есть функция
C++
1
2
3
4
BSTR DECL_SPEC x_x_5(int id)
{
    return SysAllocString(L"йцукен"); //тут на самом деле будет возврат элемента массива с номером id
}
если вызвать ее с листа книги она вернет в ячейку йцукен. если вызвать ее через обертку (как выяснил коллективный разум это необходимо для корректной передачи аргументов)
Visual Basic
1
2
3
4
5
Public Declare PtrSafe Function x_x_5 Lib "x.dll" (ByVal id As Long) As String
 
Public Function fff(ByVal id As Long) As String
  fff = x_x_5(id)
End Function
то в ячейку вернется неимоверная чушня с преобладанием символов псевдографики... W T F ? ? ?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
22.06.2016, 10:54
Все оттуда же:

How to: Access DLLs in Excel
https://msdn.microsoft.com/en-... 2147217396
Argument Types in C/C++ and VBA

You should note the following when you compare the declarations of argument types in C/C++ and VBA.

A VBA String is passed as a pointer to a byte-string BSTR structure when passed ByVal,
and as a pointer to a pointer when passed ByRef.

A VBA Variant that contains a string is passed as a pointer to a Unicode wide-character string BSTR
structure when passed ByVal, and as a pointer to a pointer when passed ByRef.
Если по-русски: VBA String получается ANSI-шная, отсюда и "чушня".
Надо запаковывать String в Variant, тогда строка будет Юникодная, в
широких символах, которая получается из SysAllocString.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,472
22.06.2016, 11:30  [ТС]
Убежденный, BSTR не юникод? пошел думать с отвалившимся мозгом...
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
22.06.2016, 11:38


BSTR - это, как правило, UTF-16 Little Endian. Как правило, но не всегда.
BSTR может использоваться как контейнер для передачи ANSI-строк и
даже (о, ужас!) двоичных данных, потому что подсистема COM "знает"
про данный тип, т.е. как передать его между процессами/компьютерами,
как определить длину данных и т.д.

См. SysAllocStringByteLen, например.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.06.2016, 11:38

Не работают комбинации в Word 2013
Скачал Word 2013, установил и т.д. Он оказался на английском - ладно, немного знаю. Но! Самое главное, что в нем не работают никакие...

Подключение сторонней библиотеки OpenCV в VS 2013
Помогите пожалуйста как разрешить конфликт подключенных файлов и стандартных библиотек сделал примерно как здесь, но в настройках...

Ошибка подключения динамической библиотеки VS 2013
Делаю всё по руководству: http://msdn.microsoft.com/ru-RU/library/ms235636.aspx В результате получаю: 1&gt;------ Сборка начата:...

Подключение библиотеки OpenCV в Visual Studio 2013
Доброго времени суток. Вопрос крайне глупый, но всё таки возникла проблема. Пытаюсь поставить openCV на visual studio 2013 по данному...

Установка библиотеки libxml++. Visual Studio 2013
Доброго всем вечера! Подскажите пожалуйста, как правильно ставить данную библиотеку? Постоянно вылезают ошибки, но из-за того, что ещё...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Альцгеймер и колоссальный объем вычислений
Programma_Boinc 08.08.2026
Альцгеймер и колоссальный объем вычислений Сейчас по направлению болезни Альцгеймера идет колоссальный объем вычислений. Это один из главных приоритетов проекта. Такой массовый наплыв задач. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru