?
Solved

Error Calling VB5 callback from C++ DLL

Posted on 1997-10-12
6
Medium Priority
?
277 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 3

Accepted Solution

by:
rmichels earned 300 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

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

The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
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…
Suggested Courses
Course of the Month8 days, 9 hours left to enroll

764 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