Вызов функции C ++ из Excel и VBA с использованием DLL, созданной в Stack Overflow

Я создал DLL, содержащую функцию с именем «koduj». Вызов этой функции с использованием ее в ячейке листа Excel возвращает желаемый результат. Вызов «кодуй» из VBA возвращает неправильный ответ.

Кодую нужны два аргумента: string nr_id а также integer x1, Рассчитывает сумму nr_idбуквы в ASCII представлении и добавляет x1, Расчетная сумма возвращается.

Я следовал найденным инструкциям Вот.

Вот мой исходный файл .cpp:

#include<Windows.h>
#include<string>
using namespace std;//Convert BSTR to wstring for convenience
wstring BSTR_to_wstring (BSTR text){
return wstring(text, SysStringLen(text));
}

//Calculate sum of letters in ASCII representation
int ASCII_sum (wstring ws){
int sum = 0;
for (unsigned int i = 0; i < ws.length(); i++)
sum += ws[i];
return sum;
}

//"koduj" function
int _stdcall koduj (BSTR nr_id, int & x1){
wstring ws_nr_id = BSTR_to_wstring(nr_id);
return ASCII_sum(ws_nr_id) + x1;
}

Вот мое объявление функции VBA:

Declare Function koduj _
Lib "<dll_directory_and_full_name>" (ByVal x As String, ByRef y As Integer) As Integer

Написав:

=koduj("aaa";1)

Внутри ячейки листа я получаю желаемый результат (292)

Отладка этого кода VBA:

Sub test()

Dim a As Integer
a = koduj("aaa", 1)

End Sub

показывает неверный результат (а = 24930)

Я считаю, что мой код C ++ в порядке, так как он работает правильно при вызове из листа Excel.

6

Решение

Причина в том, что, хотя строки VBA являются внутренними UTF-16, VB всегда преобразует их в ASCII, прежде чем говорить с внешним миром (Declared функции, файл ввода / вывода). Итак, когда вы Declare параметр As String, VBA автоматически преобразует строка и передает его как ASCII. Соответствующий тип параметра на стороне C ++ должен быть LPSTR или же LPCSTR,

Если вы хотите использовать BSTR на стороне C ++ вам также необходимо создать файл IDL для этой функции, скомпилировать его в TLB и ссылаться на TLB из VBA, только тогда VBA будет уважать и использовать BSTR,

Другая проблема в том, что C ++ int переводит на VBA Long,

Причина, по которой он работает при вызове из листа Excel, заключается в том, что игнорирует правила VBA для преобразования строк. Я считаю, что это ошибка.

2

Другие решения

Попробуй объявить как долго:
Дим как долго

0

По величине ошибки я догадываюсь, что числовой параметр работает неправильно — я бы попытался более явно объявить тип параметра в вашей тестовой подпрограмме VBA (вероятно, Integer) и принять его как этот конкретный тип на стороне C ++ (подписанный Короче, в таком случае).

Есть отличная статья Microsoft обо всем этом на http://msdn.microsoft.com/en-us/library/office/bb687915(v=office.15).aspx.

0

Не предназначен для полного ответа, но тип вашего второго параметра выглядит неправильно.

Ваша функция DLL:
int _stdcall koduj (BSTR nr_id, int & x1)
объявляет x1 как ссылка (предположительно) 32-разрядное целое число.

Ваша декларация VBA:
Declare Function koduj Lib "<dll_directory_and_full_name>" (ByVal x As String, ByRef y As Integer) As Integer
объявляет у как указатель к 16-битный целое число.

Я бы посоветовал изменить объявление VBA следующим образом:

Declare Function koduj _
Lib "<dll_directory_and_full_name>" (ByVal x As String, ByVal y As Long) As Long

И, переключая вашу сигнатуру функции DLL, чтобы передать x1 по значению

int _stdcall koduj (BSTR nr_id, int x1)

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector