Author |
Message |
Daniel Gélina #1 / 16
|
 Calling a VB function from a C++ DLL
Hi! I must call a VB function from a C++ DLL. The only way I found is with the AddressOf method. But when I try to use the function in my C++ DLL, it crashes (permorfed an illegal operation) and my VB program must close. Here's how I do it (dummy example): declare sub "DLL_Function" lib "DLLCpp.DLL" (VBFn as long) (...) 'Function call DLL_Function AddressOf(BoxFn) (...) (in my main module) Sub BoxFn(Msg as string) Msgbox Msg end sub The problem is not in VB (I create an executable file and it works well) The problem is not in passing the function to the DLL. The problem comes when I try to use the function in my DLL (it seems like the DLL can't find the function and then crashes...) Here's the C++ part: typedef void __stdcall Fn(char* Msg); void __stdcall DLL_Function(Fn* VbFunction) { (...) VbFunction("Hello world"); // Crashes here (...) Quote: }
Thanks for your help!!!
|
Tue, 15 Jan 2002 03:00:00 GMT |
|
 |
Ron Rubl #2 / 16
|
 Calling a VB function from a C++ DLL
Quote:
>Hi! >I must call a VB function from a C++ DLL. The only way I found is with the >AddressOf method. But when I try to use the function in my C++ DLL, it >crashes (permorfed an illegal operation) and my VB program must close. >The problem is not in VB (I create an executable file and it works well) >The problem is not in passing the function to the DLL. >The problem comes when I try to use the function in my DLL (it seems like >the DLL can't find the function and then crashes...) >Here's the C++ part:
I think the problem is that your function declaration is incorrect. Your VB Function is expecting a VB String (a BSTR*), containing a UNICODE string. You're passing a static character pointer. If you change the prototype and pass VB a BSTR*, it should work. You can make this easier in the long run by making the VB portion an ActiveX server. That will save a lot of the work, since VC knows how to read type libraries.
|
Tue, 15 Jan 2002 03:00:00 GMT |
|
 |
Daniel Gélina #3 / 16
|
 Calling a VB function from a C++ DLL
Quote: > I think the problem is that your function declaration > is incorrect. > Your VB Function is expecting a VB String (a BSTR*), > containing a UNICODE string. You're passing a > static character pointer. > If you change the prototype and pass VB a BSTR*, > it should work. You can make this easier in the long run > by making the VB portion an ActiveX server. > That will save a lot of the work, since VC > knows how to read type libraries.
I converted the BoxFn function to a sub without parameters; sub BoxFn() Msgbox "Hello World" end sub so that no strings can interfere in the communication process. It crashes again. So it's not a string problem (I made other tests and VB converts char* from C++ to strings in VB). So my problem remains unsolved, ans it IS a communication problem. It seems like AddressOf doesn't return the correct value, or it returns a value that C++ cannot recognize. The only other possibility I can think of, is the declaration of the DLLFunction inside the VB program: declare sub "DLL_Function" lib "DLLCpp.DLL" (VBFn as long) maybe VBFn must be something else than a long??? (ByVal long?) (VBFn is what eventually contains the address of BoxFn) Thanks for your time!
|
Tue, 15 Jan 2002 03:00:00 GMT |
|
 |
Klaus H. Probs #4 / 16
|
 Calling a VB function from a C++ DLL
Daniel, Take a look at these two KB articles -- they might help you out. Doing callbacks is rather hard, but it's not impossible at all. http://support.microsoft.com/support/kb/articles/q181/5/78.asp http://support.microsoft.com/support/kb/articles/q171/7/29.asp -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Please post/reply to the newsgroup(s) Klaus H. Probst http://members.xoom.com/kprobst/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
Quote:
> > I think the problem is that your function declaration > > is incorrect. > > Your VB Function is expecting a VB String (a BSTR*), > > containing a UNICODE string. You're passing a > > static character pointer. > > If you change the prototype and pass VB a BSTR*, > > it should work. You can make this easier in the long run > > by making the VB portion an ActiveX server. > > That will save a lot of the work, since VC > > knows how to read type libraries. > I converted the BoxFn function to a sub without parameters; > sub BoxFn() > Msgbox "Hello World" > end sub > so that no strings can interfere in the communication process. It crashes > again. So it's not a string problem (I made other tests and VB converts > char* from C++ to strings in VB). > So my problem remains unsolved, ans it IS a communication problem. It seems > like AddressOf doesn't return the correct value, or it returns a value that > C++ cannot recognize. > The only other possibility I can think of, is the declaration of the > DLLFunction inside the VB program: > declare sub "DLL_Function" lib "DLLCpp.DLL" (VBFn as long) > maybe VBFn must be something else than a long??? (ByVal long?) > (VBFn is what eventually contains the address of BoxFn) > Thanks for your time!
|
Tue, 15 Jan 2002 03:00:00 GMT |
|
 |
Patrick Escarceg #5 / 16
|
 Calling a VB function from a C++ DLL
You need to pass VBFN ByVal, otherwise VB will pass VarPtr(VBFn) to your dll, and that will of course crash... Quote: > declare sub "DLL_Function" lib "DLLCpp.DLL" (VBFn as long) > maybe VBFn must be something else than a long??? (ByVal long?) > (VBFn is what eventually contains the address of BoxFn) > Thanks for your time!
-- Patrick Escarcega patrickj AT itis DOT com Consultant Maxim Group
|
Tue, 15 Jan 2002 03:00:00 GMT |
|
 |
Jonathan Woo #6 / 16
|
 Calling a VB function from a C++ DLL
Daniel, Quote: > I must call a VB function from a C++ DLL. The only way I found is with the > AddressOf method. But when I try to use the function in my C++ DLL, it > crashes (permorfed an illegal operation) and my VB program must close. > (...) > Sub BoxFn(Msg as string) > Msgbox Msg > end sub > (...) > typedef void __stdcall Fn(char* Msg); > void __stdcall DLL_Function(Fn* VbFunction) { > (...) > VbFunction("Hello world"); // Crashes here > (...) > }
The reason this fails is because your VB routine is expecting an address of a BSTR, which is a pointer to a pointer to a Unicode string. Your DLL is passing it an LPSTR (a pointer to an ANSI string). -- Jonathan Wood SoftCircuits Programming http://www.softcircuits.com
|
Tue, 15 Jan 2002 03:00:00 GMT |
|
 |
Ron Rubl #7 / 16
|
 Calling a VB function from a C++ DLL
Quote: >The only other possibility I can think of, is the declaration of the >DLLFunction inside the VB program: >declare sub "DLL_Function" lib "DLLCpp.DLL" (VBFn as long) >maybe VBFn must be something else than a long??? (ByVal long?) >(VBFn is what eventually contains the address of BoxFn)
I think you got it. Quote: >Thanks for your time!
|
Tue, 15 Jan 2002 03:00:00 GMT |
|
 |
Richard Harriso #8 / 16
|
 Calling a VB function from a C++ DLL
can VB call functions from a DLL that uses the _CDECL Calling convention? If so how would i call this function within a dll called 'test' from VB6 DBL_FindRec(DBL_HTABLE hTable,DBL_HREC hRec, DBL_U8* searchMethod); hTable = handle to the table hRec = Record to be searched for searchmethod = a operator (= < >) Thanks. Richard.
|
Fri, 18 Jan 2002 03:00:00 GMT |
|
 |
Klaus H. Probs #9 / 16
|
 Calling a VB function from a C++ DLL
Quote: > can VB call functions from a DLL that uses the _CDECL Calling convention?
No. Only functions exported with __stdcall. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Please post/reply to the newsgroup(s) Klaus H. Probst http://members.xoom.com/kprobst/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
Quote: > can VB call functions from a DLL that uses the _CDECL Calling convention? If > so how would i call this function within a dll called 'test' from VB6 > DBL_FindRec(DBL_HTABLE hTable,DBL_HREC hRec, DBL_U8* searchMethod); > hTable = handle to the table > hRec = Record to be searched for > searchmethod = a operator (= < >) > Thanks. > Richard.
|
Fri, 18 Jan 2002 03:00:00 GMT |
|
 |
Eduardo Morcill #10 / 16
|
 Calling a VB function from a C++ DLL
Quote: > > can VB call functions from a DLL that uses the _CDECL Calling convention? > No. Only functions exported with __stdcall.
That is almost correct. Check this KB article: HOWTO: Call C Functions That Use the _cdecl Calling Convention http://support.microsoft.com/support/kb/articles/Q153/5/86.asp -- Eduardo A. Morcillo New: Read Office document properties with VB code. Free ActiveX controls, TypeLibs & Code: http://www.geocities.com/SiliconValley/Foothills/9940
|
Fri, 18 Jan 2002 03:00:00 GMT |
|
 |
Daniel Gélina #11 / 16
|
 Calling a VB function from a C++ DLL
Quote: > Daniel, > Take a look at these two KB articles -- they might help you out. Doing callbacks > is rather hard, but it's not impossible at all. > http://support.microsoft.com/support/kb/articles/q181/5/78.asp > http://support.microsoft.com/support/kb/articles/q171/7/29.asp
Ok. I changed my functions according to what they say in the articles, and it still crashes... declare sub "DLL_Sub" lib "DLLCpp.DLL" (ByVal VBFn as long) (...) 'C++ Sub call DLL_Sub AddressOf(BoxFn) (in my main module) Sub BoxFn() Msgbox "Hello World" end sub Here's the C++ part: void __stdcall DLL_Sub(long VbFnAddr) { typedef void (__stdcall *VbFn) (void); VbFn VbFunction = (VbFn) VbFnAddr; VbFunction(); // Crashes here Quote: }
I REALLY don't know what to do. I tried the example they give in the first article and it still doesn't work. I'm still looking for an answer on my own, but I'm in need of possible solutions... ;-) One of them is to test the API calls within C++ dlls only... to see if it is not a problem with windows' DLLs (installation problem...) Any suggestions? Thanks.
|
Fri, 18 Jan 2002 03:00:00 GMT |
|
 |
Klaus H. Probs #12 / 16
|
 Calling a VB function from a C++ DLL
Eduardo, Quote: > That is almost correct. Check this KB article: > HOWTO: Call C Functions That Use the _cdecl Calling Convention > http://support.microsoft.com/support/kb/articles/Q153/5/86.asp
Sure, by building a wrapper DLL. That's the only workaround, but in any case you are not calling the __cdecl DLL -- you're using a __stdcall wrapper for it. OTOH, if you have the DLL and you have the source, might as well rewrite it an switch to __stdcall if that's possible. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Klaus H. Probst http://members.xoom.com/kprobst/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
Fri, 18 Jan 2002 03:00:00 GMT |
|
 |
Daniel Gélina #13 / 16
|
 Calling a VB function from a C++ DLL
Ok. Thank you all for your help. You know, when stupidity reached my mind I learned the word Sorry. Now I can't even say I'm sorry without feeling cheap. Here's the error (and the REAL syntax of my app): declare function "RUN" lib "DLL_LINKER" (ByVal BoxFn as long) _ as string (...) Dim Result as string Result = RUN(AddressOf(BoxFn)) (...) and in my main module: sub BoxFn() Msgbox "Hello World" end sub The problem was in the declare line: I was using the same name for the argument AND for my sub!! As I said... stupidity reached my mind... ;-)) Thanks again!
|
Fri, 18 Jan 2002 03:00:00 GMT |
|
 |
Klaus H. Probs #14 / 16
|
 Calling a VB function from a C++ DLL
Glad you solved your problem, Daniel. -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Please post/reply to the newsgroup(s) Klaus H. Probst http://members.xoom.com/kprobst/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
Quote: > Ok. Thank you all for your help. You know, when stupidity reached my mind I > learned the word Sorry. Now I can't even say I'm sorry without feeling > cheap. > Here's the error (and the REAL syntax of my app): > declare function "RUN" lib "DLL_LINKER" (ByVal BoxFn as long) _ > as > string > (...) > Dim Result as string > Result = RUN(AddressOf(BoxFn)) > (...) > and in my main module: > sub BoxFn() > Msgbox "Hello World" > end sub > The problem was in the declare line: I was using the same name for the > argument AND for my sub!! > As I said... stupidity reached my mind... ;-)) > Thanks again!
|
Fri, 18 Jan 2002 03:00:00 GMT |
|
 |
Klaus H. Probs #15 / 16
|
 Calling a VB function from a C++ DLL
That was a secret, Eduardo! ;-) Actually, yes, you can do that. But it's a hack, and it's not worth the problems you'll have when Microsoft removes this "functionality", which I don't doubt they will. Plus, you can get stack corruption galore. Believe me, I tried it once with the C runtime. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Klaus H. Probst http://members.xoom.com/kprobst/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
Quote: > Eduardo, > > That is almost correct. Check this KB article: > > HOWTO: Call C Functions That Use the _cdecl Calling Convention > > http://support.microsoft.com/support/kb/articles/Q153/5/86.asp > Sure, by building a wrapper DLL. That's the only workaround, but in any case you > are not calling the __cdecl DLL -- you're using a __stdcall wrapper for it. > OTOH, if you have the DLL and you have the source, might as well rewrite it an > switch to __stdcall if that's possible.
Hi Klaus, "NOTE: An .EXE file created in Visual Basic will allow you to call a DLL function that has been declared with the _cdecl calling convention without an error. It is only when you try to call such a function when running a program from the Visual Basic IDE, that Visual Basic generates the following error: Run-time Error '49': Bad DLL Calling Convention The fact that the EXE version allows you to call such functions has been confirmed to be a bug by Microsoft. You should not rely on this behavior as this might change in future versions of Visual Basic." -- Eduardo A. Morcillo New: Read Office document properties with VB code. Free ActiveX controls, TypeLibs & Code: http://www.geocities.com/SiliconValley/Foothills/9940
|
Fri, 18 Jan 2002 03:00:00 GMT |
|
|