【问题标题】:C++ dll import in VBA(Excel) with a method declaration "_Something"使用方法声明“_Something”在 VBA(Excel)中导入 C++ dll
【发布时间】:2012-10-19 17:21:17
【问题描述】:

我最近从朋友那里得到的 c++ dll 遇到了一些问题。 我正在尝试将 dll 导入 Excel VBA 加载项。 (我使用的是 Excel 2010 32bit,dll 是在 Visual Studio 2008 中编译的)

首先我尝试导入它,但它失败并出现运行时错误 49。 我得出的结论是,它可能来自缺少的 c++ 声明 (__stdcal)。 (我认为 Visual Studio 应该自动执行此操作,但没关系)

现在我有一个新的 dll,其声明中包含 __stdcal,但方法在其开头使用下划线 (_) 声明。

所以当我尝试声明 Sub 时,Excel 会告诉我“无效字符”之类的信息 是否有可能在不更改 c++ 文件的情况下避免这种情况?

'void _SaveFile(const char *FileName_);'
Declare Sub _SaveFile Lib "D:/DLL/TableController.dll" (ByRef FileName_ As String)
            ^
            |

提前致谢

这里有一些额外的信息可能会导致我的问题的解决方案。

我现在有一些 C++ 代码来调试我的问题... 我仍然收到运行时错误 49,但依赖walker 现在给了我正确的方法名称(我认为这非常棒;))

我尝试在 C# 程序中使用相同的 dll。 正如我所料,它工作得非常正常。 这是我的 C# 代码 这是导入:

        [DllImport("JLTable.dll",CallingConvention=CallingConvention.StdCall)]
        internal static extern void JLReadFile(string _FileName);

        [DllImport("JLTable.dll", CallingConvention = CallingConvention.StdCall)]
        internal static extern long JLGetRowCount();

如果我点击一个按钮就会发生这种情况

        TableRunner.JLReadFile(@"D:\file.tab");
        long rows = TableRunner.JLGetRowCount();
        MessageBox.Show(rows.ToString());

这是我在 VBA 中的代码 声明:

    Declare Function JLReadFile Lib "D:/JLTable.dll" (ByRef FileName_ As String)
    Declare Function JLGetRowCount Lib "D:/JLTable.dll" () As Long

还有电话:

    Sub Read()
        Dim path As String
        path = "D:/file.tab"
        JLReadFile (path)
        Dim count As Long
        count = JLGetRowCount()
    End Sub

这也是我要调用的 c++ 代码。 由于某种原因,我的朋友不希望我展示代码的确切作用,但它的行为仍然与此代码相同。

.h 文件(JLTable_API 类似于#define JLTable_API __declspec(dllexport))

    #define STDCALL
    extern "C"
    {
    JLTABLE_API void STDCALL  JLReadFile(const char *FileName_);
    JLTABLE_API void STDCALL  JLSaveFile(const char *FileName_);
    }

.c++ 文件

    void STDCALL  JLReadFile(const char *FileName_)
    {
    //log something to a file
    }
    long STDCALL  JLGetRowCount()
    {
    //log something to a file
    return 0;
    }

非常感谢您能给我的每一个提示

和往常一样 提前致谢

【问题讨论】:

    标签: c++ vba dllimport


    【解决方案1】:

    我终于有办法了。 我发现一个博客告诉我我做错了什么。

    http://aandreasen.wordpress.com/2008/05/05/how-to-create-a-dll-for-ms-excel-vba-with-microsoft-visual-c-2008-command-line-tools/

    如上所述,您需要正确的方法名称,以确定哪个是正确的方法,我使用了依赖遍历器。 这最终导致我发表了这个声明

    VBA:

    Declare Sub JLReadFile Lib "D:/JLTable.dll" (ByRef FileName_ As String) Alias "_JLReadFile@4" (ByRef FileName_ As String)
    

    C++:

    void __declspec (dllexport) _stdcall JLReadFile(const char *FileName_);
    

    【讨论】:

      【解决方案2】:

      在我运行的类似测试中,您需要使用“别名”关键字。这样它就可以写成:Declare Sub SaveFile Lib "D:/DLL/TableController.dll" Alias "_SaveFile" (ByRef FileName_ As String)

      此外,我认为您不必通过引用传递文件名,但我可能是错的。自从我使用VB以来已经有一段时间了。 有关从动态库导入函数的更多信息,请查看this page out

      【讨论】:

      • 感谢您的提示,但现在它显示运行时错误 453“找不到 DLL 入口点”。我使用了依赖walker来检查一切是否正常,并问我的朋友为什么他使用下划线。他说声明没有下划线,但依赖项步行者说有一个。无论我是否使用下划线声明它,我总是会收到运行时错误 453
      • 别名应该已经解决了下划线问题。听起来该功能可能没有正确导出。虽然这可能是一种禁忌方法,但我通常会在构建 DLL 后检查我的 .def 文件以查看入口点的名称以供以后使用,有时它们可​​能会全部损坏,或者可能不会出现(这要么会解释你的问题)
      猜你喜欢
      • 2016-06-10
      • 2011-09-14
      • 1970-01-01
      • 2018-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多