Reputation: 3153
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
Reputation: 3153
I finally have a solution. i found a blog which showed me what i did wrong.
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
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