Link to home
Start Free TrialLog in
Avatar of yassin092898
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
Avatar of jhance
jhance

The problem is that VB doesn't use "C" strings (i.e. const char *).  It uses what C++ calls BSTR types.  So you need to accept the call from VB with a BSTR and then convert it to be used with a function like MessageBox() that expectes a "C" string.

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);
}
Avatar of yassin092898

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
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.


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!

ASKER CERTIFIED SOLUTION
Avatar of BeyondWu
BeyondWu
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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

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
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.

I am sorry I was out of town. I thank all BeyondWu's answer worked well.

Thanks