使用方法声明“_Something”在VBA(Excel)中导入C ++ dll

时间:2012-10-15 09:42:34

标签: c++ vba dllimport

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

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

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

所以当我尝试声明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;
    }

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

和往常一样 提前致谢

2 个答案:

答案 0 :(得分:3)

我终于找到了解决方案。 我找到了一个博客,向我展示了我做错了什么。

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

如上所述,您需要正确的方法名称,以确定哪个是我使用依赖性walker的正确方法。 这最终促成了我的宣言

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_);

答案 1 :(得分:2)

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

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