如何使用Visual Studio调试从VBA调用的C ++ DLL函数

时间:2014-07-27 08:16:15

标签: c++ excel vba excel-vba

我用C ++编写了一个DLL函数,我从VBA(Excel)调用它。

如何设置Visual Studio属性以允许我调试该功能?我已经尝试过指定Excel,但这似乎不起作用。

2 个答案:

答案 0 :(得分:3)

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

我非常喜欢"直接调试"从这里省略了很多原因的方法。

DLL和Excel / VBA方面都需要执行步骤,如果所有这些步骤都得到解决,则您的帖子不清楚。

以下内容有以下几种:

1)在VS中,根据版本,在" Debug(not release)Target"中输入Project Settings,Project Properties或等效项,进入Debug或Debugging设置。 :

a)将有一个名为" Executable的字段用于调试会话"或"命令"或类似的东西,具体取决于VS ver。在这里,输入Excel exe的完整路径

b)可选地,如果相同的"测试电子表格"经常使用,在名为"命令参数"或"程序参数"的字段中输入xls(或其他)的完整路径。或者像你的VS版本一样。

您可能需要用双引号括起来(例如,如果您的路径/文件名中有空格)。

c)您还可以将项目的输出设置为一个Dir,这是一个有用的",例如一个名为AddIn的Dir(cf将DLL最终放在Debug(或Release)Dirs中)

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

...... DLLEXPORT设置(和相关的编译器开关)和Calling Convention的细节将决定许多事情...假设您已经正确且一致地完成了所有这些(并且特别是与Excel端是什么一致)预期)。

...您的DLL可能有也可能没有DLL_Main,如果有,则需要进行更多讨论。

2)在其他任何事情之前,一定要创建Excel端"界面"为你的DLL,即。 "加载项"。这可以通过.xla或通过.xll。我强烈建议将.xla路线作为您的第一种方法。

请参阅Excel帮助文件等以创建.xla

然后,在你的XLA的VBA模块中,从你的DLL声明函数/ subs等。例如,如果你有一个名为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

我在这里使用了Alias方法,原因如下。

在许多情况下,此声明可以直接用作工作表中的用户定义函数(UDF)等。但是,对于大多数情况,您需要创建一个VBA"微调器" function / sub创建"终极" UDF,并依赖于这种直接输入功能(见下文)。这也是一个很长的故事,但在需要更复杂的事情(数组,变体等)时是必要的。

注意:

a)除非采取特殊步骤,否则需要DLL的完整路径。如果您的Addin用于一般分发...需要更长时间的讨论。

b)Alias必须是DLL中函数的EXACT条目名称。如果您在DLL(或.Def)文件的末尾附近查看,除非您将DLL模块设置为Private,否则这些将显示DLL端预期的条目名称。

在此示例中,条目名称不是"装饰"由于Calling Convention和编译器开关中的选择,但它看起来像

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

...无论如何,你必须使用DLL所拥有的任何东西。

3)一旦.xla和dll都存在(最好是它们在同一个Dir中),Excel必须被告知"关于加载项。最简单的方法是Excel / Tools / Addins,但有各种策略可以注册" DLL函数。

4)通常,参数列表属性/声明必须与您的DLL和调用约定中的属性/声明一致。三个(很多可能的)"问题"是,

(i)VBA端的布尔值是两个字节,如果你的DLL端的Bool / Logical是1字节,那么Debug将失败,因为双方"无法连接&#34 ;正常。

(ii)字符串...这可能是一个很长的故事。这取决于发送ByVal还是ByRef,它取决于DLL端是否具有"隐藏长度" Args等等。请记住,VBA使用COM / OLE VBStrings,它们有自己的蠕虫病毒。

(iii)变体/物体:这些需要自己的作品

5)如果上述所有(并且可能更多)已经顺利,那么在VS中设置您的断点,如果需要,并且" Go"或"开始"调试(取决于VS ver等)。这应该启动Excel,如果你也设置目标xls,它也将启动。转到你添加功能的单元格(例如= add2_pho_XX(A1,B1))驻留,并执行单元格(有时使用" fx"菜单项很有用,但还有其他方法)。

一些提示:

a)如果func执行崩溃/挂起等Excel并且甚至没有返回到VS端,则可能存在Arg列表冲突(例如,您正在将Double传递给Int或其他百万种可能性),或召集公约冲突等

b)通常,您可以(在VS调试会话期间)同时执行VBA调试会话。也就是说,在启动VS bebug之后,进入VBA IDE,并在VBA UDF中设置断点,如果是" spinner" 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

...这里,在第一行设置断点可以帮助查看是否甚至在VBA端输入了UDF。如果是,请单击VBA中的继续,查看它是否进入VS侧,如果没有,请再次检查Args,Calling Convention等,等等

c)如果单元格的内容是#Value或其他一些意外的结果,那么至少UDF被识别出来#34;但是由于sheet-&gt; VBA问题或VBA->导致无法正常运行DLL问题,或返回DLL-&gt;之后VBA

d)经常保存!在运行之前使用VBA IDE的Debug / Compile VBA Project,只需确保VBA内部一致性。

e)另外,如果您正在使用VBA / XLA,那么请获取一份CleanProject(VBA有时会弄乱它的内部,这个工具将是一个救生员)

答案 1 :(得分:3)

请确保调试模式为活动模式。

How to debug your DLL with Excel/VBA