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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12893002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 18:07:06  来源:igfitidea点击:

C++ dll import in VBA(Excel) with a method declaration "_Something"

c++vbadllimport

提问by Bongo

I am having some problems with a c++ dll i recently got from a friend. I am trying to import the dll into an Excel VBA Add-in. (I am using Excel 2010 32bit and the dll is compiled in Visual Studio 2008)

我最近从朋友那里得到的 c++ dll 有一些问题。我正在尝试将 dll 导入 Excel VBA 插件。(我使用的是 Excel 2010 32bit 并且 dll 是在 Visual Studio 2008 中编译的)

First of all i tried to import it but it failed with a runtime error 49. I concluded that it possibly comes from a missing c++ declaration (__stdcal). (i thought visual studio should do this automatically but okay)

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

Now i have a new dll with __stdcal in its declaration, but the methods are declared with a underscore ( _ ) at its beginning.

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

So when i try to declare the Sub, Excel tells me something like "invalid character" is there a possibility to avoid this without altering the c++ files ?

因此,当我尝试声明 Sub 时,Excel 会告诉我诸如“无效字符”之类的内容,是否有可能在不更改 C++ 文件的情况下避免这种情况?

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

Thanks in advance

提前致谢

Here are some additional informations which maybe lead to a solution for my problems.

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

I got now some c++ code to debug my problem... I still get the runtime error 49 but the dependency walker gives me now the right names of the methods( which is pretty awesome i think ;) )

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

I tried to use the same dll in an C# program. As i expected it worked perfectly normal. Here is my C# code this is the import:

我试图在 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();

annd this happens if i click a Button

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

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

Here is my code in VBA The declaration:

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

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

And the call:

和电话:

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

And Here is also the c++ code i want to call. Because of some reason my friend doesn't want me to show what the code exactly does but it still behaves the same way with this code.

这也是我想调用的 c++ 代码。由于某种原因,我的朋友不希望我展示代码的确切功能,但它仍然以与此代码相同的方式运行。

The .h file(the JLTable_API is something like #define JLTable_API __declspec(dllexport))

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

The .c++ file

.c++ 文件

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

I am very grateful for every hint you can give me

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

And as always Thanks in advance

和往常一样提前致谢

回答by Bongo

I finally have a solution. i found a blog which showed me what i did wrong.

我终于有了解决方案。我找到了一个博客,它告诉我我做错了什么。

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

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

As described you need the correct method name, to figure out which is the correct one i used the dependency walker. This finally led me to this declaration

如上所述,您需要正确的方法名称,以确定哪个是我使用依赖项walker 的正确方法。这最终使我做出了这个声明

VBA:

VBA:

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

C++:

C++:

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

回答by M4rc

From a similar test I ran, you need to use the "Alias" keyword. So that it would be written similar to: Declare Sub SaveFile Lib "D:/DLL/TableController.dll" Alias "_SaveFile" (ByRef FileName_ As String)

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

Additionally, I don't think you have to pass filename by reference, but I could be wrong. It's been a while since I've used VB. More information on importing functions from a dynamic library, check thispage out

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