2016-03-06 63 views
0

你好,我正在尝试创建一个简单的C++ dll来在Excel中使用。在excel中使用C++ dll时没有考虑到的参数

这里是我做过什么:

.cpp文件:

double _stdcall Test(double z) 
{ 
    return z+2.0; 
} 

DEF文件:

LIBRARY 
EXPORTS 
Test 

在Visual Studio: 项目属性>配置属性>命令>“ Path/EXCEL.EXE“

配置管理器>平台> x64

在VBA:

Declare PtrSafe Function Test Lib _ 
"Path\MyDLL" (ByVal z As Double) As Double 

但是,当我打电话测试(2)在Excel中,它返回2,而不是4看起来说法被视为0送花儿给人(其实如果我产值在调用该函数时在一个文件中,它是2.122e-314)。

任何输入将不胜感激。

感谢

编辑1: 如果我改变参数和返回值INT与VBA龙,测试(2)返回3

任何人有一个想法,为什么参数为1诠释?

+0

一切都适合我。您是否记得将模块定义文件设置为您的.def文件?这是什么'项目属性>配置属性>命令>“路径/ EXCEL.EXE”'。我没有这样的选择。 – ly000

+0

如果我不这样做,我得到以下错误: “路径/ MyDLL.dll”不是有效的Win32应用程序。 事情是,def文件可能工作正常,因为函数被调用,只是没有考虑Excel参数 –

+0

您的C++编译器不知道该函数正在导出。所以它期望参数传递的方式不同,浮点是通过SSE指令完成的,参数通过XMM0寄存器传递。然而,Excel假定参数应该以传统方式通过FPU寄存器ST0。把'__declspec(dllexport)'放在函数前面来解决这个问题。 –

回答

0

道歉:本来张贴这作为注释,但还不能:

第一:你的函数可以导出为C++重整名称。 使用extern“C”来防止名称损坏。还有其他方法可以做到这一点,但这是最直接的。但是,如果测试功能被成功调用,我不确定这是否是问题。

使用extern“C”你的C函数看起来像这样。

extern "C" 
double _stdcall Test(double z) 
{ 
    return z+2.0; 
} 

第二:你是否完全肯定你正在选择正确的DLL,而不是缺少修正的旧DLL?尝试将函数名称更改为源和Excel VBA封装器中更具体的内容。

第三:如果您未在64位Excel系统上运行,请在VB中从您的函数规范中删除PtrSafe声明并重新编译为32位。

第四:不要试图直接从Excel单元调用您的DLL。将函数包装在VBA中(下例)或使用CALL函数。

下面的代码是一个如何包装写入VBA单元函数的示例。

Public Function CellFunction_Test(x As Double) As Double 
'' Tells excel to call this function only if the inputs change 
'' and not on every recalculation 
Application.Volatile False 

'' Set an error handler, good practise for more complicated functions you might write later 
On Error GoTo CellFunction_Test_EH: 

'' Call into the DLL 
CellFunction_Test = Test(x) 
Exit Function 

'' Error Handler 
CellFunction_Test_EH: 
CellFunction_Test = "Error - " & Err.Description 
End Function 
+0

您好,非常感谢您加入您的意见,非常感谢。 1.我添加了外部“C”行。没有改变任何东西。 2.再次尝试使用新项目,所以我肯定是的,但仍然没有运气。 3.我正在运行一个x64 Excel 2013版... 我可以在Excel中调试程序,并且函数确实被调用。但是,就像在Excel调用和C++执行之间清理堆栈一样。因为如果按值传递,z的值是2e-314,并且如果通过引用传递它,则无法读取内存异常,并在C++函数参数列表中给出地址。 也许这说明了 –

+0

您是直接从Excel单元格调用此函数(例如= TEST(2))还是从VBA函数调用宏函数或其他函数? – JimmyNJ

+0

谢谢大家,第四点为我解决了!非常感谢你,但我不知道为什么...... –