【发布时间】:2015-09-04 07:55:30
【问题描述】:
这是我遇到的一个奇怪的行为。 我有一个用于用户的 Visual Basic 界面。
Declare PtrSafe Sub getPEC _
Lib "C:\Users\...somePath...\OPunit0011PUMP.dll" _
(ByVal typeOfPump As Integer, _
ByVal outflow As Double, _
ByRef pec As Double, _
ByRef RV As Integer)
用户通过整数 typeOfPump 指定泵。我将此参数作为 ByVal typeOfPump 传递到我的 C++ DLL 中。 这里根据哪个泵,一些预先声明的参数 a,...g 使用 switch case 进行初始化
extern "C"
{
double PEC_backUp;
void __stdcall getPEC(int typeOfPump, double outflow, double &PEC, int &RV)
{
//polynomal trendline for different pumps
//y = a x^6 + b x^5 + c x^4 + d x^3 + e x^2 + f x^1 + g x^0
if (typeOfPump < 1)
{
RV = -1;
return;
}
double a, b, c, d, e, f, g;
#pragma region switch case
switch (typeOfPump)
{
//150 bar
case 1:
a = 1.1186E-08;
b = -1.49172E-05;
//...
break;
case 2:
//...
}
我的问题是开关盒不起作用。我的默认值设置为九,但其他所有情况都不起作用。它只是忽略了 switch case 代码。 另请注意:在 If 条件中可以看到相同的奇怪行为:
if (typeOfPump > 1)
{
RV = -1;
return;
}
尽管 typeOfPump 被分配给 NINE 这显然比一个大,但我的函数 getPEC 在这一点上没有返回。另一方面,如果我写
if (typeOfPump < 1)
{
RV = -1;
return;
}
我的函数将返回这里。然后我将 typeOfPump 的值分配给 RV 以在 VBA 中对其进行监控,并将 RV 设置为 9。
此外,为了让事情变得更奇怪,当它返回 RV = -1 时,它会自动将 pec 的值更改为 7.00000000005821(使用 VBA 的 watch 函数)。
我猜我的参数在某种程度上与我的 DLL 中的操作不兼容。以前有没有人看到过这个,我该如何解决? 提前谢谢!
编辑:我可以做类似的操作
RV = typeOfPump * (int)outflow;
并获得正确的值。但是,pec 的值仍然显示出一些变化。
SCD 编辑: 我有 64 位,Excel 是 32 位,我正在用 x86 编译。 我在另一台 64 位计算机上写了一个类似的程序,Excel 64 位,用 x64 编译。成功了!
第三次编辑: VBA 中值 9 的整数导致 C++ 环境中的 -65526,给定我的 C++ 环境中的整数大小为4字节。假设整数的 16 位变量的范围是 -32,768 到 32,767。将 32,767 加倍并减去 9 得到 65525。
【问题讨论】:
-
我认为这是一个 VBA 问题,而不是 VB.net:
PtrSafe是一个 VBA 关键字,用于标记可以从 64 位 Excel 安全调用的函数据我所知。查看msdn.microsoft.com/en-us/library/office/… 以了解 32/64 位兼容性。 -
正确,OP 还进行了编辑删除了我的评论。
-
一个 VBA
Integer是 16 位。你有没有在dll中打印出typeOfPump并查看它的值? -
抱歉回复晚了。如果输入值为 9,则我的 MessageBox 打印:-65526。
-
在我的例子中,DLL 中的整数变量包含 4 个字节(使用了 sizeof 运算符)。我还读到 VBA 的整数有 32 位,所以分别有 4 个字节(比较:msdn.microsoft.com/en-gb/library/06bkb8w2.aspx)或者我在某些时候误导了。无论如何,我怎样才能防止这个错误?
标签: c++ vba if-statement dll switch-statement