Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Обмен данными типа String между VBA и C++ DLL / 25 сообщений из 26, страница 1 из 2
21.04.2009, 02:54
    #35943233
dgulet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
Здравствуйте, уважаемые форумчане!
Кажется здесь еще не обсуждалась эта тема - как организовать обмен строковыми данными между офисными VBA-приложениями и простыми (не COM) DLL, написанными на С++. Туда и обратно.

Работаю над лингвистическим проектом. Написав программу на VBA под MS Word, которая работает с массивами данных типа String, пришел к выводу, что при увеличении объема данных программа начнет "тормозить". Для ускорения работы некоторых функций решил переписать их на С++ и загнать в DLL. Начал с простых попыток обмена данными, но столкнулся с тем, что строки (слова) в формате BSTR VBA неправильно передаются в DLL. Я не специалист в с++. Начал им заниматься недавно в Vsual Studio 2005. Ниже приведен код функций, которые удачно экспортируются в dll, но дают некорректный результат. Непонятно, в каком виде доходит string до dll? Нужна ваша помощь непрофессионалу.

Код: plaintext
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.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
//---------------------------------DLL    
//работает неправильно (видимо ищет подстроку...)
// пробовал и другие операторы сравнения, безрезультатно...


#include "stdafx.h"
#include <string>
#include <iostream>


using namespace std;

string *WeekdayRu;

bool WINAPI DaNet( char *ss)
{
bool nalichie = false;
for(int k= 0 ; k< 7 ; k++)
{
    if (ss == WeekdayRu[k]) {nalichie = true; break;}
}

//MessageBox (0, ss, "Заголовок", MB_OK);   // хорошо бы здесь выводить значение ss, но не получается - компилятор выдает ошибки

return nalichie;
}

// функция загружает данные в память (массив указателей WeekdayRu)
int WINAPI Zagruzka()
{
 WeekdayRu = new string[ 7 ];
 
string SlovaRu[] = {"Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"};
for(int i= 0 ; i< 7 ; i++)
{
WeekdayRu[i] = SlovaRu[i];
}
return  0 ;
}


Для VBA:
Public Declare Function Zagruzka Lib "C:\Mojadll.dll" () As Long
Public Declare Function DaNet Lib "C:\Mojadll.dll" (ByVal ss As String) As Boolean
---------------------------------------------------------------------------------------
Sub mydll()

Zagruzka
Dim Slovo As String
Slovo = "пятница" 'если я набираю "ятница" или "ница" - все равно возвращает "True" (почему ???)
MsgBox DaNet(Slovo)

End Sub
...
Рейтинг: 0 / 0
21.04.2009, 10:13
    #35943488
~PJ
~PJ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
dgulet,

в VB

Private Declare Sub ExtracAll Lib "extotms_.dll" (ByVal filename As String)

в С++ h модуле обяви например :

extern "C" void __declspec(dllexport) __stdcall ExtracAll(char * fileName);
...
Рейтинг: 0 / 0
21.04.2009, 11:15
    #35943667
pszMyNick
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
Попробуйте так.
Код: plaintext
MessageBox ( 0 , ss.c_str(), "Заголовок", MB_OK);
...
Рейтинг: 0 / 0
21.04.2009, 17:51
    #35945177
dgulet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
~PJ,

Пишу строку
extern "C" void __declspec(dllexport) __stdcall ExtracAll(char * fileName);
в stdafx.h - компилятор выдает 4 ошибки.


pszMyNick,

Попробовал
MessageBox (0, ss.c_str(), "Заголовок", MB_OK);
компилятор выдает 1 ошибку - must have class/struct/union
...
Рейтинг: 0 / 0
21.04.2009, 21:40
    #35945610
~PJ
~PJ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
dgulet,

прошу прощения это я дал для компиляторов C++ Builder . Возможно там небольшое отличие.
...
Рейтинг: 0 / 0
22.04.2009, 03:16
    #35945832
dgulet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
Главное, мне бы понять, почему в следующем фрагменте
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
bool WINAPI DaNet( char *ss)
{
bool nalichie = false;
for(int k= 0 ; k< 7 ; k++)
{
    if (ss == WeekdayRu[k]) {nalichie = true; break;}
}

//MessageBox (0, ss, "Заголовок", MB_OK);   // хорошо бы здесь выводить значение ss, но не получается - компилятор выдает ошибки

return nalichie;
}


происходят ошибки при сравнении?:
if (ss == WeekdayRu[k])
Т.е. при явном несовпадении строковых значений функция возвращает True.
...
Рейтинг: 0 / 0
22.04.2009, 10:52
    #35946239
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
потому что бессмысленно сравнивать указатель на char с экземпляром класса std::string. Для сравнения строк стоит использовать функцию strcmp() или её аналоги. Или, как вариант, из входного параметра тоже сконструировать объект типа std::string, и тогда уже сравнивать.
...
Рейтинг: 0 / 0
22.04.2009, 16:44
    #35947677
dgulet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
egorych,
благодарю за указание. Вы правы. Я и прежде пытался сравнивать строки используя оператор strcmp().
Только не получалось. Видимо я невнимательно отнесся к параметрам функции (см. MSDN):
int strcmp( const char *string1 const char *string2);
Нада было, наоборот, преобразовать std::string * в const char *. Вот так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
bool WINAPI DaNet(const char *ss)
{
bool nalichie = false;
for(int k= 0 ; k< 7 ; k++)
{
    if (strcmp (ss, WeekdayRu[k].c_str()) ==  0 ) {nalichie = true; break;}
}
return nalichie;
}
Теперь работает корректно.
Всем СПАСИБО.
...
Рейтинг: 0 / 0
22.04.2009, 17:10
    #35947779
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
ну можно и так написать:
Код: plaintext
1.
2.
3.
4.
5.
6.
bool WINAPI isWeekday( const std::string &searchDay )
{
   for( int i =  0 ; i <  7 ; ++i ) 
      if ( searchDay == WeekdayRu[ i ] ) return true; 
   
   return false;
}
...
Рейтинг: 0 / 0
25.04.2009, 17:48
    #35954040
dgulet
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
А как определить количество букв в элементе массива WeekdayRu[k],
или длину элемента?
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
10.06.2013, 22:35
    #38293291
hey ho
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
Джентельмены, а вот такой вопрос - хочу также распознать текст из VBA, передаю его в С++ как ByVal String, принимаю как char. Далее использую switch:

case 'B':
return 111;
break;

case 'BA':
return 222;
break;

Если текст начинается с B, то всегда получается 111 :(
Как этого избежать, используя switch?

PS как видите, я ламер :)
...
Рейтинг: 0 / 0
11.06.2013, 00:02
    #38293347
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
hey ho, case 'BA' должен, как минимум, варнинг при компиляции порождать, вероятно, не зря
...
Рейтинг: 0 / 0
11.06.2013, 09:25
    #38293477
Кот Чеширский
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
dgulet Написав программу на VBA под MS Word, которая работает с массивами данных типа String, пришел к выводу,

А почему VBA не под Excel?
...
Рейтинг: 0 / 0
13.06.2013, 20:59
    #38296945
hey ho
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
egorychhey ho, case 'BA' должен, как минимум, варнинг при компиляции порождать, вероятно, не зря
Намекаете на то, что switch работает с однобуквенными вариантами?
Я погуглил и не нашёл, ранее сталкивался с тем, что однобуквенные работали, многобуквенные нет. Что где не так делаю?
Попробовал то же самое через if else, там тоже не выходит (руки мои оттуда растут, да!).
В идеале мне нужно запилить функцию типа x(ABC100500XYZ;N), распарсить её на ABC, 100500 и XYZ и в зависимости от значений этих компонентов, вернуть обратно в VBA результаты типа 100500/N или 100500^N.
...
Рейтинг: 0 / 0
13.06.2013, 21:52
    #38296978
hey ho
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
Погуглил ещё, понял что мою проблему через char не решить. Теперь делаю так:
VBA
Declare PtrSafe Function analysis Lib "blahblah.dll" (ByVal word As String, ByRef N as Double) As Double

C++
#include <iostream>
#include <string>
double __stdcall analysis(std::string & code, double & N)
{
if (word == "ABC") return 111;
else
if (code == "BAC") return 222;
else
return 666;
}

на этой петрушке всё компилится, но при пересчёте экселя он падает.
Кто найдёт шайтана?
...
Рейтинг: 0 / 0
13.06.2013, 22:19
    #38296997
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
hey hoКто найдёт шайтана?
сам ищи :)

ByVal word As String в С приедет как LPCSTR
строки сравнивать функцией strcmp

пример- http://support.microsoft.com/kb/187912/ru
...
Рейтинг: 0 / 0
13.06.2013, 23:07
    #38297022
hey ho
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
Изопропил, теперь вот как:
C++
#include <iostream>
#include <string>
#include <windows.h>
double __stdcall analysis(LPCSTR code, double & N)

{
if (!strcmp(word, "ABC")) return 111;
else
if (!strcmp(word, "BAC")) return 222;
else
return 666;
}

Компилится, эксель не падает, но выдаёт 666 в любом случае.
...
Рейтинг: 0 / 0
13.06.2013, 23:35
    #38297041
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
hey ho,

в отладчике смотри что происходит
...
Рейтинг: 0 / 0
14.06.2013, 00:03
    #38297066
hey ho
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
Изопропилhey ho,

в отладчике смотри что происходит
Я dll в связке с Excel не знаю как отлаживать :(
...
Рейтинг: 0 / 0
14.06.2013, 00:13
    #38297082
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
hey hoВ идеале мне нужно запилить функцию типа x(ABC100500XYZ;N), распарсить её на ABC, 100500 и XYZ и в зависимости от значений этих компонентов, вернуть обратно в VBA результаты типа 100500/N или 100500^N.в идеале надо в VBA распарсить, и не мучать себе и окружающим мозги ;-))
...
Рейтинг: 0 / 0
14.06.2013, 00:26
    #38297097
hey ho
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
egorychв идеале надо в VBA распарсить, и не мучать себе и окружающим мозги ;-))
В VBA уже сделано. Сверху парсинга ещё калькуляций прилично, поэтому скорость уже играет роль.
...
Рейтинг: 0 / 0
14.06.2013, 00:37
    #38297115
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
hey hoИзопропилhey ho,

в отладчике смотри что происходит
Я dll в связке с Excel не знаю как отлаживать :(
добавить в солюшн эксель (excel.exe), задать параметры, установить контрольные точки и запустить безобразие
...
Рейтинг: 0 / 0
14.06.2013, 01:20
    #38297151
hey ho
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
Изопропилдобавить в солюшн эксель (excel.exe), задать параметры, установить контрольные точки и запустить безобразие
Спасибо, буду пробовать.
...
Рейтинг: 0 / 0
17.06.2013, 22:04
    #38300727
hey ho
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
Что-то не выходит :(
Разбираюсь с типами данных, пишут, что LPCSTR и "текст в двойных кавычках" (лулз,ну не знаю я как оно правильно называется) нельзя сравнивать. Как правильно конвертнуть?

PS подумав о том как жить дальше, твёрдо решил записаться на курсы С++ :)
Кстати, кто чего может в Москве посоветовать? Или может кто уроки даёт?
...
Рейтинг: 0 / 0
18.06.2013, 00:36
    #38300811
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обмен данными типа String между VBA и C++ DLL
hey ho,
>> Разбираюсь с типами данных, пишут, что LPCSTR и "текст в двойных кавычках" (лулз,ну не знаю я как оно правильно называется) нельзя сравнивать. Как правильно конвертнуть?
strcmp() спасёт отца русской демократии

>> PS подумав о том как жить дальше, твёрдо решил записаться на курсы С++ :) Кстати, кто чего может в Москве посоветовать?
дом книги на новом арбате посети
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Обмен данными типа String между VBA и C++ DLL / 25 сообщений из 26, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]