Click to See Complete Forum and Search --> : Got Callback to work, but now different problem... crash


bcyde
October 19th, 1999, 12:51 PM
With some help I was able to get a callback to a DLL to work and pass the correct parameter values back and forth (by changing the callback function to a callback sub), however after the sub is called and does what it is supposed to do the program crashes with the following error it has a long description, so whatever I'm doing wrong must be pretty bad :) :

Microsoft Visual C++ Debug Library
Debug Error!
Program: (the app)
Module:
File i386\chkesp.c
Line: 42

The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convetion with a function pointer declared with a different calling convention.

That's basically it. If anyone wants source code or can help in any way I would greatly appreciate it.
Thanks

Sky1000
October 19th, 1999, 05:29 PM
Did you accept the callback object, by value, in the dll. For example, in your dll you have a class ( MyCoolClass) and an ICallback class with the template function ICalllback_Notify(strMess as String), you implement a callback class (Callback) in the main exe application (Implements ICallback) and it's function Callback_ICallback_Notify(strMess as String) will handle the callback. Your dll class MyCoolClass delcares an ICallback object but it will not be instansiated (Dim m_Callback as ICallback). Then declare a function or sub you want to pass the object from your app to say, MyCoolSub(byval p_Callback as ICallback). In this subrountine instansiate your callback object to point to the passed parameter, Set m_Callback = p_CallBack. In your app you declare and instansiate a callback object ( Dim MyCallback as New Callback) and a MyCoolClass object. You pass your callback object as follows, MyCoolClass1.MyCoolSub(MyCallback). Then when you need to send a callback to the Application, you can use the m_Callback object in MyCoolClass, for example, m_Callback.Notify("Proccess Done").

Sky1000

bcyde
October 20th, 1999, 03:43 PM
Sorry if I seem very newbie-ish, but your reply was pretty much over my head. The DLL I created was a test and is very simple. Here's what the whole code looks like for the source file:

__declspec( dllexport ) int i;
void __stdcall MyCFunction(void (*LPCALLBACK)(int))
{
i=702;
(*LPCALLBACK)(i);
}

and here is the .def file:

LIBRARY testdll
EXPORTS
MyCFunction
i DATA

the VB form looks like this:

Private Sub Command1_Click()
Call MyCFunction(AddressOf how)
End Sub

and finally the module looks like:

Declare Function MyCFunction Lib "testdll.dll" (ByVal lngFnPtr As Long) As Long

Sub how(ByVal alma As Integer)
MsgBox ("The How function is being called by the MyCFunction and is being passed " & alma)
End Sub

If you can provide me with some guidance I would greatly appreciate it. The error message eludes me since I have no idea what i386\chkesp.c is.

Ravi Kiran
October 21st, 1999, 05:13 AM
Hi,

I tried this and it seems to work!!..

What it does is, calls the C-dll, which will call the VB function back after incrementing the passed in value by 10.

This is my C dll code:- File :C2VBCallback.c

#define DllExport __declspec( dllexport )

long DllExport __stdcall CallMeBack(int (__stdcall *lpcallback)(int i), long lOrigval )
{
lpcallback(lOrigval + 10);
return 0;
}

In C2VBCallback.def these lines:

LIBRARY "C2VBCallback"
EXPORTS
CallMeBack

In VB Project, add a module:

option Explicit
public Declare Function CallMeBack Lib "C2VBCallback.dll" (byval lpFunc as Long, byval lInpVal as Long) as Long

Sub Main()
Load Form1
CallMeBack AddressOf VBCallbaclFunc, 10
Form1.Show
' When the form shows, it will show 20 (10 + 10) in the label
End Sub

public Function VBCallbaclFunc(byval lValue as Long) as Long
Debug.print lValue
VBCallbaclFunc = 1
' Update the Form1's label with the value
' passed in.
Form1.Label1.Caption = Str(lValue)
End Function
[vbcode]

Add a form and a label. Compile the dll, copy to VB prog's directory and run.
Or Compile the Vb program. compile the dll. Copy the VB program to dll directory and run.
Or specify the Full path to dll in declare statment.

' I also added this code in the form:
[vbcode]
option Explicit

Dim lVal as Long
private Sub Command1_Click()
CallMeBack AddressOf VBCallbaclFunc, lVal

' label gets the value updated from the DLL-callback function.
' so take that value and update the variable
lVal = CLng(Label1.Caption)
End Sub





With each click, the value increments by 10, (which is done in C-section), and Updates label ( done in VB section)

AND It works w/o creashing:-). For some time, it was giving the standard Error 49, because i forgot the __stdcall for the C export function.


RK

Ravi Kiran
October 21st, 1999, 05:53 AM
Well!, it even supports Break Points (run from VB IDE) and Msgboxes.
I was not willing to try that in the first sample because, i have some prior expr with subclassing giving problems.. :-)

RK

bcyde
October 21st, 1999, 01:48 PM
Thanks so much for replying. I was actually able to get it to work (a little bit differently than your implementation) right before getting your response. Thanks again!