[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 280
  • Last Modified:

Error Calling VB5 callback from C++ DLL

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
jcdixon
Asked:
jcdixon
  • 3
  • 3
1 Solution
 
rmichelsCommented:
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
 
jcdixonAuthor 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
0
 
rmichelsCommented:
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!

 
jcdixonAuthor 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.
0
 
rmichelsCommented:
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
 
jcdixonAuthor Commented:
Thanks.  The byte array inside of a structure works fine.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now