Solved

Error Calling VB5 callback from C++ DLL

Posted on 1997-10-12
6
275 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
0
Comment
Question by:jcdixon
  • 3
  • 3
6 Comments
 
LVL 3

Accepted Solution

by:
rmichels earned 100 total points
ID: 1437423
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.
0
 

Author Comment

by:jcdixon
ID: 1437424
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
0
 
LVL 3

Expert Comment

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

void _declspec(dllexport) __stdcall CleanUp()

0
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 

Author Comment

by:jcdixon
ID: 1437426
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.
0
 
LVL 3

Expert Comment

by:rmichels
ID: 1437427
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.
0
 

Author Comment

by:jcdixon
ID: 1437428
Thanks.  The byte array inside of a structure works fine.
0

Featured Post

Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question