DLL function not working in a VBA environment but working in Excel VBA

c++, excel, string, vba

Solution

Turns out something was wrong with the string I've been importing. I do not understand what, since when I debugged the program, they looked fine. I solved by importing a `SAFEARRAY` of strings (which required me to change the whole function and the VBA code as well), whose `BSTR` value could be accessed as follows:

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);
    }

Having converted all the `BSTR`s in `wstring`s correctly, I could work with `wregex`s without any problem.

Problem

I have the following function contained in a DLL I wrote (c++) that I debugged in Excel, and worked just fine: ``` 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; } ``` If `FileName` is for example `foo_T024.lol`, this function correctly returns a `float` (in C++, or `Single` in VBA) with the value of 2.4 . I call the function from VBA (both from Excel and the other environment) as: ``` Private Declare Function ReturnT Lib "[myDLLname]" (ByVal FileName As String) As Single ``` If I do the same from the other environment and use the function on the same string, I get an `**ERROR**` and sadly nothing else, because I can't debug (being this a proprietary application). What could be the problem? EDIT: I found out that this other environment is actually SAX, which is basically identical to VBA. EDIT: I managed to link Visual Studio with the application, so I could check what's imported and what is wrong. `FileName` looks correctly imported, (I used also a `VARIANT`-input approach to see if that was the issue, which it wasn't) but I receive an error at this line: ``` wregex ToFind(L"_[tT]\\d{2,3}(\\_|\\.)"); ``` The error is: Unhandled exception at 0x75F0C54F in NSI2000.exe: Microsoft C++ exception: std::regex_error at memory location 0x0018E294. And it stops by `xthrow.cpp` at this point: ``` #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: My VS version is 2013, the platformtoolset is the "Visual Studio 2013 - Windows XP (v120_xp)". My compiler version is: "Version 18.00.21005.1 for x64"

Original source

Related problems