Solved

Error Calling VB5 callback from C++ DLL

Posted on 1997-10-12
6
272 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
Comment Utility
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
Comment Utility
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
Comment Utility
what does your function (in C++) prototype/definition look like.  In my DLLs my functions look as follows:

void _declspec(dllexport) __stdcall CleanUp()

0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:jcdixon
Comment Utility
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
Comment Utility
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
Comment Utility
Thanks.  The byte array inside of a structure works fine.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
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…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
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…

763 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now