Bongo
Bongo

Reputation: 3153

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

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)

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)

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

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 ?

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

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:

        [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:

    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.

The .h file(the JLTable_API is something like #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

    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

Upvotes: 1

Views: 6606

Answers (2)

Bongo
Bongo

Reputation: 3153

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/

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

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

Upvotes: 3

M4rc
M4rc

Reputation: 503

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)

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 this page out

Upvotes: 2

Related Questions