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"
You can access DLL functions and commands in VBA by using the Declare statement. This statement has one syntax for commands and one for functions. The optional Public and Private keywords specify the scope of the imported function: the entire Visual Basic project or just the Visual Basic module, respectively.
DLLs (dynamic-link libraries) are portable libraries that can be created by one application and used by another. In particular one can create a DLL in C then have its functions run from Excel by calling them from VBA.
Your DLL files are located in C:\Windows\System32.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With