yassin092898
asked on
CPP Dll for VB
I want to write a dll for VB program. I am using Visual Studio 6.
My CPP dll exports one function that receaves one string parameter.
here it is.
extern "C" void __cdecl fnTen(const char* name)
{
MessageBox(NULL, name , "Function Called", 0);
}
and here is VB program that calls the dll function.
Private Declare Function fnCallXapi Lib "CVBDll.dll" Alias "fnTen" (ByVal s As String)
Private Sub Command1_Click()
Dim i As Long
Dim name As String
name = "John"
On Error GoTo hError
Call fnCallXapi(name)
MsgBox i
Exit Sub
hError:
MsgBox "Error " & Err.Description
End Sub
When the dll function is called it shows the MessageBox but it doesn't display the name I passed and I get the erro message "Bad Dll calling convection"
Thanks
My CPP dll exports one function that receaves one string parameter.
here it is.
extern "C" void __cdecl fnTen(const char* name)
{
MessageBox(NULL, name , "Function Called", 0);
}
and here is VB program that calls the dll function.
Private Declare Function fnCallXapi Lib "CVBDll.dll" Alias "fnTen" (ByVal s As String)
Private Sub Command1_Click()
Dim i As Long
Dim name As String
name = "John"
On Error GoTo hError
Call fnCallXapi(name)
MsgBox i
Exit Sub
hError:
MsgBox "Error " & Err.Description
End Sub
When the dll function is called it shows the MessageBox but it doesn't display the name I passed and I get the erro message "Bad Dll calling convection"
Thanks
ASKER
I made the changes but still getting the "Bad Dll calling convection" error message
Here is my entire dll code
#include "stdafx.h"
#include <comdef.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" void __cdecl fnTen(BSTR name)
{
_bstr_t mBstr(name, FALSE);
MessageBox(NULL,char *)mBstr , "Function Called", 0);
}
and here is the VB Code
Private Declare Function fnCallXapi Lib "CVBDll.dll" Alias "fnTen" (ByRef s As String)
Private Sub Command1_Click()
Dim i As Long
Dim name As String
name = "Yassin"
On Error GoTo hError
Call fnCallXapi(name)
MsgBox i
Exit Sub
hError:
MsgBox "Error " & Err.Description
End Sub
Thanks for the help
Here is my entire dll code
#include "stdafx.h"
#include <comdef.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" void __cdecl fnTen(BSTR name)
{
_bstr_t mBstr(name, FALSE);
MessageBox(NULL,char *)mBstr , "Function Called", 0);
}
and here is the VB Code
Private Declare Function fnCallXapi Lib "CVBDll.dll" Alias "fnTen" (ByRef s As String)
Private Sub Command1_Click()
Dim i As Long
Dim name As String
name = "Yassin"
On Error GoTo hError
Call fnCallXapi(name)
MsgBox i
Exit Sub
hError:
MsgBox "Error " & Err.Description
End Sub
Thanks for the help
That's another issue. Change the _cdecl to _stdcall. VB uses the stdcall calling convention (formerly known as _pascal) where C and C++ use _cdecl.
ASKER
Here is the program after the changes but I am strill getting "Bad Dll calling convection".
#include "stdafx.h"
#include <comdef.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" void __stdcall fnTen(BSTR name)
{
_bstr_t mBstr(name, FALSE);
MessageBox(NULL, (char *)mBstr , "Function Called", 0);
}
Thanks
Change your argument data type from BSTR to LPSTR and try again!
Good luck!
Good luck!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I had the similar problem before. In my case, two corrections in my VC++ 6 program got by the error in VB 6 client.
1. As jhance suggested, use __stdcall declaration
2. In your VC++ program, insert a new <yourdll>.DEF file
Add the following code:
LIBRARY CWaveUtil.dll
DESCRIPTION 'Compuwave Utility library 1.0'
EXPORTS
; DllRegisterServer @1
; DllUnRegisterServer @2
; Explict export goes here
CWLen @10
1. As jhance suggested, use __stdcall declaration
2. In your VC++ program, insert a new <yourdll>.DEF file
Add the following code:
LIBRARY CWaveUtil.dll
DESCRIPTION 'Compuwave Utility library 1.0'
EXPORTS
; DllRegisterServer @1
; DllUnRegisterServer @2
; Explict export goes here
CWLen @10
Sorry! Previous comment was a folly.
Correction for DEF file:
LIBRARY CVBDll.dll
DESCRIPTION 'Dll library 1.0'
EXPORTS
fnTen @1
Will work.
Good luck!
James
Correction for DEF file:
LIBRARY CVBDll.dll
DESCRIPTION 'Dll library 1.0'
EXPORTS
fnTen @1
Will work.
Good luck!
James
1. Open the dll with the program "depends" and see the names you are actually exporting from the dll.
2. I use __declspec(dllexport) in the declaration to avoid needing a def file.
3. Actual bug -- You are passing the BSTR* BvVal, not ByRef, so change to ...ByVal s As String... in the VB -- BSTR* in C == String in VB.
4. Split the problem in 2. Don't put any code in the dll function until you can call it successfully.
5. Getting sub vs. function is not fatal. The only difference is the interpretation of EAX, not a stack difference.
2. I use __declspec(dllexport) in the declaration to avoid needing a def file.
3. Actual bug -- You are passing the BSTR* BvVal, not ByRef, so change to ...ByVal s As String... in the VB -- BSTR* in C == String in VB.
4. Split the problem in 2. Don't put any code in the dll function until you can call it successfully.
5. Getting sub vs. function is not fatal. The only difference is the interpretation of EAX, not a stack difference.
ASKER
I am sorry I was out of town. I thank all BeyondWu's answer worked well.
Thanks
Thanks
One way to do this would be to use the C++ _bstr_t class from comdef.h:
extern "C" void __cdecl fnTen(BSTR name)
{
_bstr_t mBstr(name, FALSE);
MessageBox(NULL, (char *)mBstr , "Function Called", 0);
}