9 votes

La fonction DLL ne fonctionne pas dans un environnement VBA mais fonctionne dans Excel VBA

J'ai la fonction suivante contenue dans une DLL que j'ai écrite (c++), que j'ai déboguée dans Excel, et qui fonctionne parfaitement :

float _stdcall ReturnT(LPCSTR FileName)
{

// Extracts the generic language string from the (importing BSTR  
// would import kanji or whatever) and converts it into a wstring
wstring str = CA2T(FileName);

// Sets the string to find as _t or _T followed by 2 or 3 digits and a subsequent _ or .
wregex ToFind(L"_[tT]\\d{2,3}(_|.)");
wsmatch TStr;

regex_search(str, TStr, ToFind);    // Now the wsmatch variable contains all the info about the matching
wstring T = TStr.str(0).erase(0, 2);    // Removes the first 2 characters
T.erase(T.end() - 1);               // Removes the last character

// Checks if T is 3 digits or not (2 digits) and eventually add a "."
wstring TVal = L"";
if (T.size() == 3)
{
    TVal += T.substr(0, 2) + L"." + T.substr(2, 3);
}
else if (T.size() == 2)
{
    TVal += T;
}

// Converts T string to a float
const float TValue = (float) _wtof(TVal.c_str());

return TValue;
}

Si FileName est par exemple foo_T024.lol cette fonction renvoie correctement un float (en C++, ou Single en VBA) avec la valeur de 2,4 .

J'appelle la fonction depuis VBA (à la fois depuis Excel et l'autre environnement) comme suit :

Private Declare Function ReturnT Lib "[myDLLname]" (ByVal FileName As String) As Single

Si je fais la même chose à partir de l'autre environnement et que j'utilise la fonction sur la même chaîne, j'obtiens une **ERROR** et malheureusement rien d'autre, car je ne peux pas déboguer (s'agissant d'une application propriétaire).

Quel pourrait être le problème ?

EDIT : J'ai découvert que cet autre environnement est en fait SAX qui est fondamentalement identique à VBA.

EDIT : J'ai réussi à lier Visual Studio avec l'application, afin de pouvoir vérifier ce qui est importé et ce qui ne va pas. FileName semble correctement importé, (j'ai aussi utilisé un VARIANT -pour voir si c'était le problème, ce qui n'était pas le cas) mais je reçois une erreur à cette ligne :

wregex ToFind(L"_[tT]\\d{2,3}(\\_|\\.)");

L'erreur est :

Exception non gérée à 0x75F0C54F dans NSI2000.exe : Exception Microsoft C++ : std::regex_error à l'emplacement mémoire 0x0018E294.

Et il s'arrête xthrow.cpp à ce stade :

#if _HAS_EXCEPTIONS

#include <regex>

_STD_BEGIN
_CRTIMP2_PURE _NO_RETURN(__CLRCALL_PURE_OR_CDECL _Xregex_error(regex_constants::error_type _Code))
    {   // report a regex_error
    _THROW_NCEE(regex_error, _Code);
    }                                     <--- Code stops here
_STD_END
 #endif /* _HAS_EXCEPTIONS */

EDIT : Ma version de VS est 2013, le platformtoolset est le "Visual Studio 2013 - Windows XP (v120_xp)". La version de mon compilateur est : "Version 18.00.21005.1 pour x64".

2voto

Noldor130884 Points 566

Il s'avère que quelque chose n'allait pas avec la chaîne que j'ai importée. Je ne comprends pas quoi, puisque lorsque j'ai débogué le programme, elles semblaient correctes. J'ai résolu le problème en important une SAFEARRAY de chaînes (ce qui m'a obligé à modifier l'ensemble de la fonction ainsi que le code VBA), dont les BSTR peut être consulté comme suit :

int _stdcall FilenameSort(LPSAFEARRAY* StringArray)
{
    // Fills a vector with the wstring values
    char** StrPtr = 0;
    long LowerBound = 0;  SafeArrayGetLBound(*StringArray, 1, &LowerBound);
    long UpperBound = 0;  SafeArrayGetUBound(*StringArray, 1, &UpperBound);
    const long Dimension = UpperBound - LowerBound;
    SafeArrayAccessData(*StringArray, reinterpret_cast<void**>(&StrPtr));

    BSTR element;
    vector<wstring> wstrArr;

    for (long i = 0; i <= Dimension; ++i)
    {
        SafeArrayGetElement(*StringArray, &i, &element);
        wstring ws(element, SysStringLen(element));
        wstrArr.push_back(ws);
    }

Ayant converti tous les BSTR en wstring correctement, je pourrais travailler avec wregex sans aucun problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X