DLL函数在VBA环境中不起作用,但在Excel VBA中工作
DLL function not working in a VBA environment but working in Excel VBA
我在 Excel 中调试的 DLL (c++) 中包含以下函数,并且工作正常:
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;
}
例如,如果FileName
是foo_T024.lol
,则此函数正确返回值为 2.4 的float
(以 C++ 表示,或在 VBA 中以Single
表示)。
我从 VBA(来自 Excel 和其他环境)调用该函数,如下所示:
Private Declare Function ReturnT Lib "[myDLLname]" (ByVal FileName As String) As Single
如果我从其他环境中执行相同的操作并在相同的字符串上使用该函数,我会得到一个**ERROR**
,可悲的是没有别的,因为我无法调试(这是一个专有应用程序)。
可能是什么问题?
编辑:我发现这个其他环境实际上是SAX,它基本上与VBA相同。
编辑:我设法将Visual Studio与应用程序链接,因此我可以检查导入的内容和错误的内容。FileName
看起来正确导入,(我还使用了VARIANT
输入方法来查看这是否是问题所在,但事实并非如此),但我在此行收到错误:
wregex ToFind(L"_[tT]\d{2,3}(\_|\.)");
错误是:
NSI2000.exe 中0x75F0C54F处未处理的异常:内存位置 0x0018E294 Microsoft C++异常:std::regex_error。
它在这一点上停了下来xthrow.cpp
:
#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 */
编辑:我的VS版本是2013,平台工具集是"Visual Studio 2013 - Windows XP(v120_xp)"。我的编译器版本是:"版本 18.00.21005.1 for x64">
事实证明,我一直在导入的字符串有问题。我不明白是什么,因为当我调试程序时,它们看起来很好。我通过导入SAFEARRAY
字符串来解决(这需要我更改整个函数和 VBA 代码),其BSTR
值可以按如下方式访问:
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);
}
正确转换了wstring
s 中的所有BSTR
后,我可以毫无问题地使用wregex
s。
- 代码在main()中运行,但在函数中出现错误
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 断言中的Fold表达式在某些计算机上编译,但在其他计算机上不编译
- 换位表导致测试失败(但在游戏中运行良好)
- 库标题在标题中不可见,但在 cmake build 下.cpp文件中完全可见.为什么?
- 树莓上的 Libtorch 无法加载 pt 文件,但在 ubuntu 上工作
- 在成员dynamic_bitset上使用 boost::from_block_range 时出错,但在本地dynamic
- 编译在我的 Mac 上工作,但在集群 (Linux) 上不起作用
- 我编写了代码将十进制分数转换为其二进制等效数.它编译得很好,但在执行时挂起
- 我的代码运行良好,但在游戏循环中中断
- C++ assigment std::list:<typename>:itrator 在 main 中工作,但在方法中它不起作用
- C++代码在台式机上工作正常,但在笔记本电脑上则不行
- 实现 DFS 在较短的输入下工作正常,但在较大的输入下会抛出分段错误
- 点云库在VS 2019中不起作用,但在VS 2017中确实有效
- C++ Python 模块在 Blender 中崩溃,但在 Python 控制台中不会崩溃
- 分段 Linux Ubuntu 中的 g++ 错误,但在 Windows 中的 g++/MingW 中,在 C++ 中打
- DLL函数在VBA环境中不起作用,但在Excel VBA中工作
- Excel 64位中的C函数不作为工作表函数,但在VBA中工作得很好