We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now

x

Error Calling VB5 callback from C++ DLL

jcdixon
jcdixon asked
on
Medium Priority
300 Views
Last Modified: 2008-02-26
I created simple VB5 and C++ programs to implement a VB callback.  The callback functions are called, but then a fatal error results when returning from the C++ dll.  Here are the sample programs and the resulting error. What am I doing wrong?

VB

Private Declare Function Start5erca Lib "lindoS.dll" (ByVal MsgPtr As String, ByVal fp1 As Long, ByVal fp2 As Long) As Long

Public Function LindoStatus(ByVal dbl1 As Double, ByVal dbl2 As Double) As Long
    MsgBox "LindoStatus:  They called me with these arguments!  " & dbl1 & "  " & dbl2
    LindoStatus = 1
End Function

Public Function RCAStatus(ByVal msg As String) As Long
    MsgBox "RCAStatus:  They called me with this message!  " & msg
    RCAStatus = 1
End Function

Public Sub Main()
    Dim MsgPtr As String * 200
    If Start5erca(MsgPtr, AddressOf RCAStatus, AddressOf LindoStatus) = 1 Then
        MsgBox "Everything is great!"
    Else
        MsgBox "Something went wrong!"
    End If
   
End Sub

C++

int Start5erca(char * MsgPtr, int (* pfRCAStatus)(char*), int (* pfLindoStatus)(double, double) ) {

      pfLindoStatus(2.0, 1.0);
      pfRCAStatus("I am ok");

      return 1;

}



CALLBACK caused an invalid page fault in
module KERNEL32.DLL at 0137:bff858c0.
Registers:
EAX=100380dc CS=0137 EIP=bff858c0 EFLGS=00010212
EBX=20492020 SS=013f ESP=100000e0 EBP=100380c4
ECX=c409da14 DS=013f ESI=10038180 FS=2c77
EDX=bffbf9e0 ES=013f EDI=10038164 GS=0000
Bytes at CS:EIP:
55 a1 78 c2 fb bf 8b ec 83 ec 70 8b 08 53 56 89
Stack dump:
ffecbad7 10000110 100000f4 0000000e 00000007 c0000005 00000000 00000000 bff858c0 00000002 00000001 100001e8 0001001f 00000000 00000000 00000000
Comment
Watch Question

Commented:
Change your code to include the __stdcall keyword in front of the callback declarations

int Start5erca(char * MsgPtr, int ( __stdcall * pfRCAStatus)(char*), int (__stdcall * pfLindoStatus)(double, double) )

You are probably having stack cleanup problems, which appear when you try to exit from your C++ function.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

Commented:
I changed the code exactly as you indicated and now when the Start5erca call returns I get the following VB error:

Run-time error '49':
Bad DLL calling convention

Commented:
what does your function (in C++) prototype/definition look like.  In my DLLs my functions look as follows:

void _declspec(dllexport) __stdcall CleanUp()

Author

Commented:
The only C++ code that I wrote is what is listed above so I'm not sure which function prototype you're referring to other than the ones in the argument list to Start5erca.  I did play around and find that I can avoid the "Bad DLL calling convention" error if I change the declaration to:

int __stdcall Start5erca( ... )
    ^^^^^^^^^
However, the RCAStatus callback that is expecting a string argument is not receiving the string that I'm passing from the C++ DLL so it's still not working properly.

Commented:
Oops I missed that on first review of the code (just looking for dll calling problems).  As far as I know you can't pass a string from a C DLL into a VB callback function.  THe VB function expects the string to be a VB string NOT and ASCIIZ C string.

I tried messing around with a byte array coming from the C++ dll but got protection violations.  What I have done in my code is to create a user defined structure that contains byte arrays.  Using the same structure C but use char arrays instead of byte arrays.  Then pass the user defined structure (ByRef) into the call.  Then take the byte arrays and rebuild them into a VB string.  My code just looped thru the byte array and concatenated a string out of each byte using CHR$.  Not the most efficient but my code was not time intensive.  C also has BSTRING types, I think they can be used for VB, but not real sure.  Never used them.

Author

Commented:
Thanks.  The byte array inside of a structure works fine.
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.