|
From: jlcaverlyca@yahoo.ca on 3 Jul 2005 13:09 Hi, I'm using MicroFocus Visual Object Cobol Product Version 1.0.27 and Visual Basic 5.0 SP3. After doing some Googling, I've created my first Cobol DLL, which I have compiled, and have called from VB5. The Cobol DLL code is as follows; IDENTIFICATION DIVISION. PROGRAM-ID. COBDLL. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. CALL-CONVENTION 3 IS WINAPI. DATA DIVISION. WORKING-STORAGE SECTION. LINKAGE SECTION. * * Short (Integer) S9(4) Comp-5 * Long (Long) S9(8) Comp-5 * 01 VB-SHORT PIC S9(4) COMP-5. 01 VB-LONG PIC S9(8) COMP-5. 01 VB-CHAR PIC X(5). PROCEDURE DIVISION WINAPI. PROC-1. ENTRY "testcall" USING BY VALUE VB-SHORT BY VALUE VB-LONG BY REFERENCE VB-CHAR. IF VB-SHORT > VB-LONG MOVE "A > B" TO VB-CHAR MOVE ZERO TO RETURN-CODE ELSE MOVE "B > A" TO VB-CHAR MOVE 1 TO RETURN-CODE END-IF EXIT PROGRAM. My VB5 code is as follows; Module1.bas: Declare Sub TESTCALL Lib "cobdll.dll" _ (VBShort As Integer, VBLong As Long, ByVal VBChar As String) Form1.bas: Private Sub Form_Load() Dim thestring As String * 5 Dim num1 As Integer Dim num2 As Long num1 = 1 num2 = 2 TESTCALL num1, num2, thestring MsgBox thestring End End Sub A couple of questions. First, I have to Declare the Sub as TESTCALL, as the DLL compiles this as UpperCase. I found this out by doing a DUMPBIN on the DLL. How do I make the DLL compile the Sub as testcall or TestCall? Second, as I step through the code in VB5 after TESTCALL, num1 becomes 8258, num2 is 2, and thestring is still five spaces. When I make num1 = 2 and num2 = 1, after TESTCALL num1 becomes 8258, num2 is 1, and thestring is still five spaces. I have a feeling that my problem may be in the CALL-CONVENTION, but I'm not sure what to change it to. Thanks in advance to anyone who knows what the problem is. Joe
From: epc8 on 3 Jul 2005 15:37 jlcaverlyca(a)yahoo.ca wrote: > Hi, > I'm using MicroFocus Visual Object Cobol Product Version 1.0.27 and > Visual Basic 5.0 SP3. > > After doing some Googling, I've created my first Cobol DLL, which I > have compiled, and have called from VB5. > > My VB5 code is as follows; > > Module1.bas: > Declare Sub TESTCALL Lib "cobdll.dll" _ > (VBShort As Integer, VBLong As Long, ByVal VBChar As String) > > A couple of questions. > First, I have to Declare the Sub as TESTCALL, as the DLL compiles this > as UpperCase. I found this out by doing a DUMPBIN on the DLL. How do I > make the DLL compile the Sub as testcall or TestCall? 1. Does the "case" directive you included in a recent post have any effect on the symbols your program *exports*? 2. add an ALIAS "TESTCALL" to your declare, then you can call your Sub whatever you want. 3. add a .def file to your build (somehow) which contains EXPORTS myname=TESTCALL > > Second, as I step through the code in VB5 after TESTCALL, num1 becomes > 8258, num2 is 2, and thestring is still five spaces. > > When I make num1 = 2 and num2 = 1, after TESTCALL num1 becomes 8258, > num2 is 1, and thestring is still five spaces. > > I have a feeling that my problem may be in the CALL-CONVENTION, but I'm > not sure what to change it to. > Usually if your calling convention is off, you get a run time error from VB. The calling convention must be stdcall for which WINAPI is an older synonym. Passing the string from Basic ByVal looks right. See http://supportline.microfocus.com/examplesandutilities/nesamp.asp for some examples from NetExpress.
From: epc8 on 3 Jul 2005 19:24 jlcaverlyca(a)yahoo.ca wrote: > Hi, > I'm using MicroFocus Visual Object Cobol Product Version 1.0.27 and > Visual Basic 5.0 SP3. > > After doing some Googling, I've created my first Cobol DLL, which I > have compiled, and have called from VB5. > > The Cobol DLL code is as follows; > > IDENTIFICATION DIVISION. > PROGRAM-ID. COBDLL. > ENVIRONMENT DIVISION. > CONFIGURATION SECTION. > SPECIAL-NAMES. > CALL-CONVENTION 3 IS WINAPI. > DATA DIVISION. > WORKING-STORAGE SECTION. > LINKAGE SECTION. > * > * Short (Integer) S9(4) Comp-5 > * Long (Long) S9(8) Comp-5 > * > 01 VB-SHORT PIC S9(4) COMP-5. > 01 VB-LONG PIC S9(8) COMP-5. > 01 VB-CHAR PIC X(5). > > PROCEDURE DIVISION WINAPI. > PROC-1. > > ENTRY "testcall" USING BY VALUE VB-SHORT > BY VALUE VB-LONG > BY REFERENCE VB-CHAR. > > IF VB-SHORT > VB-LONG > MOVE "A > B" TO VB-CHAR > MOVE ZERO TO RETURN-CODE > ELSE > MOVE "B > A" TO VB-CHAR > MOVE 1 TO RETURN-CODE > END-IF > > EXIT PROGRAM. > > My VB5 code is as follows; > > Module1.bas: > Declare Sub TESTCALL Lib "cobdll.dll" _ > (VBShort As Integer, VBLong As Long, ByVal VBChar As String) > > Form1.bas: > Private Sub Form_Load() > Dim thestring As String * 5 > Dim num1 As Integer > Dim num2 As Long > num1 = 1 > num2 = 2 > TESTCALL num1, num2, thestring > MsgBox thestring > End > End Sub > See my other message. This time I'm looking at your COBOL program in more depth. VB passes arguments by reference unless you specify ByVal. However, you do want to pass the string ByVal, otherwise you would pass a pointer to a string descriptor instead of a pointer to the string. On the COBOL side, I think changing your BY VALUE to BY REFERENCE for the two integers might help. Lastly, I'm not certain that your two COMP-5 items are really different sizes. They might be. But if you really were passing them by value before and your program did not crash, then I suspect that you were really passing 3 4-byte arguments. VB is calling a subroutine in the dll as if it takes 3 pointers. [Sorry, I have not written any VB callable DLLs in COBOL, but I have done so in a variety of other languages.]
From: jlcaverlyca@yahoo.ca on 4 Jul 2005 13:56 epc8(a)juno.com wrote: > See my other message. This time I'm looking at your COBOL program in > more depth. VB passes arguments by reference unless you specify ByVal. > However, you do want to pass the string ByVal, otherwise you would pass > a pointer to a string descriptor instead of a pointer to the string. > > On the COBOL side, I think changing your BY VALUE to BY REFERENCE for > the two integers might help. > > Lastly, I'm not certain that your two COMP-5 items are really different > sizes. They might be. But if you really were passing them by value > before and your program did not crash, then I suspect that you were > really passing 3 4-byte arguments. VB is calling a subroutine in the > dll as if it takes 3 pointers. > > [Sorry, I have not written any VB callable DLLs in COBOL, but I have > done so in a variety of other languages.] I have changed my VB Declare to pass the numerics as ByVal. I have also been looking at some of the other code on the net that has "CALL-CONVENTION .. IS WINAPI. I noticed that alot of these were 74, instead of the 3 that I was using. So, I changed it to 74. I re-compiled the DLL, and it now works as it should. I changed the values of num1 and num2 to make sure that "A > B" and "B > A" are correctly displayed from VB. I looked up in the VisOC help, and found "Call Conventions for Interfacing with Mixed Languages", which breaks down how a call convention number is determined. Here's how I interpret it; 1001010 - 74 ||||||| Process parameters from right-to-left ||||||- Parameters removed from stack by called program |||||-- RETURN-CODE is updated on exit ||||--- Call is resolved at link time |||---- Reserved (always 0) ||----- Reserved (always 0) |------ The call conforms to the Windows stdcall calling convention 0000011 - 3 ||||||| Process parameters from left-to-right ||||||- Parameters removed from stack by called program |||||-- RETURN-CODE is updated on exit ||||--- Normal linking behavior |||---- Reserved (always 0) ||----- Reserved (always 0) |------ The call does not conform to the Windows stdcall calling convention I think that making the call conform to the Windows stdcall calling convention may have had something to do with it. Many thanks for your assistance. Joe
From: epc8 on 4 Jul 2005 15:39
jlcaverlyca(a)yahoo.ca wrote: > > I have changed my VB Declare to pass the numerics as ByVal. I have also > been looking at some of the other code on the net that has > "CALL-CONVENTION .. IS WINAPI. I noticed that alot of these were 74, > instead of the 3 that I was using. So, I changed it to 74. > > I re-compiled the DLL, and it now works as it should. I changed the > values of num1 and num2 to make sure that "A > B" and "B > A" are > correctly displayed from VB. > > I looked up in the VisOC help, and found "Call Conventions for > Interfacing with Mixed Languages", which breaks down how a call > convention number is determined. Here's how I interpret it; > > 1001010 - 74 > ||||||| Process parameters from right-to-left > ||||||- Parameters removed from stack by called program > |||||-- RETURN-CODE is updated on exit > ||||--- Call is resolved at link time > |||---- Reserved (always 0) > ||----- Reserved (always 0) > |------ The call conforms to the Windows stdcall calling convention > > 0000011 - 3 > ||||||| Process parameters from left-to-right > ||||||- Parameters removed from stack by called program > |||||-- RETURN-CODE is updated on exit > ||||--- Normal linking behavior > |||---- Reserved (always 0) > ||----- Reserved (always 0) > |------ The call does not conform to the Windows stdcall calling > convention > > I think that making the call conform to the Windows stdcall calling > convention may have had something to do with it. > > Many thanks for your assistance. > > Joe Confusion arose here because WINAPI has been used as a synonym for two different things, convention 3 in 16 bit Windows (FAR PASCAL) and convention 74 in 32 bit Windows (stdcall). Sorry I missed it earlier :-(. We can blame the C programmers for this one! Yes, with the right set of header files, I can define a C function as being FAR PASCAL and it will still compile and run on Windows XP. |