2014-07-27 156 views
4

我已经使用C++编写了一个DLL函数,我从VBA(Excel)调用该函数。我该如何调试使用Visual Studio从VBA调用的C++ DLL函数

如何设置Visual Studio属性以允许我调试该函数?我试图指定Excel,但似乎并不奏效。

+1

从理论上讲,在Visual Studio中打开DLL项目设置上有问题的线路断点,然后安装调试器EXCEL.EXE。 –

+1

我试过了。但它没有工作.. – user3778269

+0

我绝对有效。我过去做过。可能这个答案有帮助:http://stackoverflow.com/a/12862488/413337 – Codo

回答

3

您有两种选择:“直接调试”或“附加”。

我非常喜欢“直接调试”方法,因为这里省略了一长串原因。

在DLL和Excel/VBA这两个方面都需要一些步骤,如果所有这些步骤都已解决,那么您的发布不清楚。

有以下变化:

1)VS,根据版本,在“调试(不释放)目标”进入项目设置,或项目属性,或等效,转到调试或调试设置。 :

a)将会有一个名为“Executable for debugging session”或“command”或类似的字段,取决于VS ver。 b)或者,如果经常使用相同的“测试电子表格”,请在名为“Command argument”的字段中输入xls(或其他)的完整路径,或“程序参数”或在您的VS版本。

您可能需要用双引号包围它(例如,如果路径/文件名中有空格)。

c)你还可以设置你的项目的迪尔的输出,“插件内容”,如迪尔称为加载项(具有DLL CF在调试(或释放结束)迪尔斯)

...假设您的DLL具有导出函数所需的所有位,项目是DLL类型的,加上任何DLLEXPORT和编译器指令等等等。

... DLLEXPORT设置的细节(和相关的编译器开关)和Calling Convention将决定许多事情......假定您已经完成了所有正确和一致的事情(特别是与Excel方面期待的一致)。

......你的DLL可能有或没有DLL_Main,如果有的话,需要更多的讨论。

2)在开始之前,一定要为您的DLL创建Excel端“接口”,即。 “加载项”。这可以通过.xla或通过.xll。我强烈建议将.xla路线作为您的第一个途径。

请参阅Excel的帮助文件等,为创建.xla

然后,在你的XLA的VBA模块(们),将您的DLL声明的功能/潜艇等。举例来说,如果你有一个名为Add2_DLL.dll DLL,它包含导出函数“add2_pho_xl”,则:

Public Declare Function Add2_Pho_XX Lib "E:\EclipseWorkSpace\Add2_DLL\Debug\Add2_DLL.dll" _ 
Alias "add2_pho_xl" (A As Double, B As Double) As Double 

我在这里使用的别名方法,下面需要的原因。

在很多情况下,这个声明可以直接作为用户定义函数(UDF)在你的工作表中使用,等等。但是,对于大量的情况,您需要创建一个创建“最终”UDF的VBA“spinner”函数/ sub,并依赖于此直接输入函数(请参见下文)。这也是一个很长的故事,但在需要更复杂的事物(数组,变体等)时是必要的。

注意:

一)需要的DLL的完整路径,除非采取特殊措施。如果您的Addin用于广泛分发......需要更长时间的讨论。

b)别名必须是DLL中函数的EXACT条目名称。如果您在DLL(或.Def)文件的末尾附近查看,并且除非将DLL模块设置为“专用”,否则这些文件将显示DLL侧所需的条目名称。

在这个例子中,条目名称不是“装饰”由于调用约定和编译器开关的选择,但它可能看起来像

“_add2_pho_xl_ @ 08”等取决于你的选择。

...在任何情况下,您必须使用任何DLL。

3)一旦.xla和dll都存在(最好是它们在同一个目录中),Excel必须被“告知”该加载项。最简单的方法是Excel/Tools/Addins,但有多种“注册”DLL函数的策略。

4)CRUCIALLY,参数列表属性/声明必须与您的DLL和调用约定中的参数列表属性/声明相同。 “问题”的三个(很多可能的)例子是,

(i)如果你的DLL端的Bool /逻辑是1字节,那么VBA端的布尔值是2个字节,那么调试将会失败,因为双方“无法正确连接”。 (ii)字符串...这可能是一个很长的故事。它取决于是否发送ByVal或ByRef,它取决于DLL端是否具有“隐藏长度”参数等。请记住,VBA使用COM/OLE VBStrings,它们有自己的蠕虫。

(III)的变种/对象:这些要求的大部头到自己

5)如果以上的ALL(可能更多)进展顺利,那么在VS设置你的破发点,如果需要的话,和“去“或”启动“调试(取决于VS版本等)。这应该启动Excel,并且如果您还设置了目标xls,它也会启动。转到加载函数所在的单元格(例如= add2_pho_XX(A1,B1))驻留并执行单元格(有时使用“fx”菜单项很有用,但也有其他方法)。

一些提示:

一)如果FUNC执行崩溃/挂起等Excel和甚至不回VS侧到达,那么很可能是一个精氨酸列表冲突(例如,你传递一个双至Int或一百万其他可能性)或呼叫约定冲突等。

b)通常,您可以(在VS调试会话期间)同时执行VBA调试会话。也就是说,在启动VS bebug之后,如果创建了“微调器”UDF,则将VBA IDE置入并在VBA UDF中设置中断点。例如,VBA UDF也依赖于DLL的功能。

Private Function Add2_Pho(FirstNum as Double, SecondNum as Double, Optional lMakeRed as Variant) As Variant 
' 
' 
Add2_Pho = Add2_Pho_XX(FirstNum, SecondNum) ' this is the actual DLL func accessed via Delcare above 
' 
If(IsMissing(lMakeRed)) Then 
Else 
    If(cBool(lMakeRed)) Then 

     If(Add2_Pho < 0) Then 
      ' 
      ' ' make the result Red, or something 
      ' 
     End If 

    End If 
End If 
' 
' 
End Function 

...在这里,在第一行设置一个中断点可以帮助您查看UDF是否被输入到VBA端。如果是,请单击VBA中的继续,并查看它是否进入VS侧,如果不是,再次检查参数,呼叫约定等,等等。

c)如果单元格的内容是#Value或其他意外的结果,那么由于sheet-> VBA问题或VBA-> DLL问题,或者在返回DLL-> VBA之后,至少UDF被“识别”但不能正常工作。d)经常保存!并在运行任何操作之前使用VBA IDE的调试/编译VBA项目,只要确保VBA内部一致。

E)另外,如果你正在使用VBA/XLA的,然后得到CleanProject(VBA可以搞砸的拷贝其内部有时,这个工具将是一个生命的救星)

相关问题