我正在尝试在Delphi XE5中创建一个64位DLL,以便与64位版本的Excel 2013进行通信,但没有任何成功。将问题分解为最简单的形式,我写了这个简单的代码:
library test64;
function xx(x : double) : double; stdcall;
begin
Result := x*2;
end;
exports
xx;
end.
我知道stdcall;不需要,但保持它与32位兼容(它在32位完美工作)。删除它不会改变任何事情,只会被忽略。
并在Win64平台上编译。在Excel 2013 x64中声明此函数如下:
Declare PtrSafe Function xx Lib "my path here\Win64\Debug\dll\test64.dll" (ByVal x As Double) As Double
现在,如果单元格A2 = XX(A1),它总是给我零。 A1中的浮点值始终从DLL侧读取为零(我也在调试模式下检查它)。但是,DLL到Excel的输出有效,即如果是:
Result := 100;
然后A2会读100.我想我正在做一些非常错误但我无法弄清楚它是什么。有什么帮助吗?提前谢谢。
PS。 64位版本需要declare语句上的完整DLL路径。 32位没有(即在与工作表相同的路径中找到DLL)。确实很奇怪......
答案 0 :(得分:1)
注意: 问题的原始版本包含省略ByVal
的不同代码。
默认参数传递模式为ByRef
。您没有指定ByVal
或ByRef
,因此使用默认值。 ByRef
不正确。您的功能与ByRef
不匹配。
因此您需要明确指定ByVal
。
Declare PtrSafe Function xx Lib "..." (ByVal x As Double) As Double
我认为你在32位模式下可以避免这种情况,因为Double
比寄存器大,所以参数是通过地址传递的。但是在64位下,参数会在寄存器中传递。
另一个问题是您无法直接从工作表中调用外部函数。您需要将调用包装到VBA函数中的外部函数,并从工作表中调用该函数。
Public Function Callxx(ByVal x As Variant) As Variant
Callxx = xx(x)
End Function