Я хочу скомпилировать DLL в C++, а затем вызвать библиотеку из VBA. Я сделал это на битах Windows32. Но я хотел воспроизвести такое упражнение, так как я использую Windows 64 бит на работе. Учитывая этот факт, я снизил объем 64.
Мой пример:
main.h
#ifndef __MAIN_H__
#define __MAIN_H__
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
extern "C"
{
int DLL_EXPORT __stdcall add2(int num);
int DLL_EXPORT __stdcall mult(int num1, int num2);
}
#endif // __MAIN_H__
main.cpp
#include "main.h"
int DLL_EXPORT __stdcall add2(int num)
{
return num + 2;
}
int DLL_EXPORT __stdcall mult(int num1, int num2)
{
int product;
product = num1 * num2;
return product;
}
Когда я компилирую dll, я передаю следующие параметры компоновщика:
Wl,--add-stdcall-alias
и/или
Wl,--kill-at
Я также создаю файл.def, который выглядит следующим образом:
EXPORTS
add2 @1
mult @2
Я ожидал файл.def, который выглядит так (как на моем 32-битном ПК):
EXPORTS
add2 @1
mult @2
add2 = add2 @1
mult = mult @2
Затем я вызываю dll и функции из VBA следующим образом:
Public Declare PtrSafe Function add2 _
Lib "C:\MyPath\dll.dll" _
(ByVal num As Long) As Long
Проблема в том, что функции можно вызывать из редактора VBA и давать правильные результаты, но при вызове из листа Excel они бросают другое число (адрес переданного аргумента?). Если я попытаюсь вызвать функцию из VBA AFTER, которую я попробовал в Excel, то VBA выдает ошибку (из стека Space).
Эта проблема отсутствует, когда я использую mingw4.7 32bit. Проблема в том, когда я компилирую с помощью mingw 4.6.3 64bit (я установил mingw4.7 64bit, но я нашел в Интернете. Люди говорят, что 4.6.3 более стабильна)
Я также заметил, что файл.def выглядит идентично одному выше, даже если я не передаю параметры компоновщика.
Может ли кто-нибудь помочь? что происходит? это mingw64 или vba/Excel feiling? или моя конфигурация mingw64?
UPDATE.... ok Я нашел этот сайт: https://sites.google.com/site/jrlhost/links/excelcdll#array и, как объясняю его, используя функцию itermediate в VBA, моя функция add2 Works из рабочего листа.
Public function fromWorksheetAdd2 ( dim x as Long) as Long
fromWorksheetAdd2 = add2(x)
end function
то я могу использовать fromWorksheetAdd2 на листах и Add2 в VBA. Однако этот подход довольно утомительный. Надеюсь, кто-то может помочь с элегантным подходом.
Посмотрите на свои параметры.
A Long в VBA - 64 бита (8 байтов). На стороне C++ размер int зависит от размера sizeof (int), что более чем вероятно 4 байта в среде, которую вы используете.
Вы должны гарантировать, что типы, которые вы отправляете и возвращаете между VBA и C++, имеют точно такой же размер, иначе вы можете столкнуться с повреждением стека.