Vassilis Papanikolaou
Vassilis Papanikolaou

Reputation: 23

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

I am trying to create a 64bit DLL in Delphi XE5 in order to communicate with the 64bit version of Excel 2013, yet without any success. Breaking down the problem to its simplest form, I wrote this simple code :

library test64;

function xx(x : double) : double; stdcall;
begin
    Result := x*2;
end;

exports
    xx;

end.

I know that stdcall; is not needed, but kept it for compatibility with 32bit (it works perfectly in 32bit). Removing it doesn't change a thing, it is just ignored.

and compiled it in Win64 platform. Declared this function in Excel 2013 x64 as follows :

Declare PtrSafe Function xx Lib "my path here\Win64\Debug\dll\test64.dll" (ByVal x As Double) As Double

Now if cell A2 = XX(A1) it always gives me zero. The floating value in A1 is always read as zero from the DLL side (I checked it in debug mode as well). However, the output from DLL to Excel works, i.e if it was :

Result := 100;

then A2 would read 100. I suppose that I am doing something terribly wrong but I cannot find out what it is. Any help please ? Thanks in advance.

PS. 64bit version needs the full DLL path on the declare statement. 32bit does not (i.e. finds the DLL in the same path as the worksheet). Strange indeed...

Upvotes: 0

Views: 536

Answers (1)

David Heffernan
David Heffernan

Reputation: 612963

Note: The original version of the question included different code which omitted the ByVal.

The default parameter passing mode is ByRef. You didn't specify ByVal or ByRef and so the default is used. And ByRef is not correct. Your function does not match ByRef.

So you need to explicitly specify ByVal.

Declare PtrSafe Function xx Lib "..." (ByVal x As Double) As Double

I think that you get away with this in 32 bit mode because Double is larger than a register and so the parameter is passed by address. But under 64 bit the parameter is passed in a register.

The other problem is that you cannot call an external function directly from a worksheet. You need to wrap the call to the external function in a VBA function, and call that function from the worksheet.

Public Function Callxx(ByVal x As Variant) As Variant

    Callxx = xx(x)

End Function

Upvotes: 1

Related Questions