Delphi Excel 2013 64 位的 XE5 64 位 DLL - 奇怪的行为

Delphi XE5 64 bit DLL for Excel 2013 64 bit - Strange behaviour

我正在尝试在 Delphi XE5 中创建一个 64 位 DLL,以便与 Excel 2013 的 64 位版本进行通信,但没有成功。将问题分解为最简单的形式,我写了这个简单的代码:

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 位版本需要声明语句中的完整 DLL 路径。 32 位没有(即在与工作表相同的路径中找到 DLL)。确实奇怪...

注意:问题的原始版本包含不同的代码,省略了ByVal

默认参数传递方式为ByRef。您没有指定 ByValByRef,因此使用默认值。而 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