Highlighted
Absent Member.
Absent Member.
2260 views

[archive] delphi and wrun32.dll

[Migrated content. Thread originally posted on 03 February 2005]

I wonder if anyone successfully tried calling the runtime dll from delphi code?

I am trying, but my parameters never seem to get passed along to the cobol program.

I defined the 'acucall' procedure like this in delphi :

function AcuCall( Name: string; var arg0: Variant; var arg1: Variant;
var arg2: Variant; var arg3: Variant; var arg4: Variant;
var arg5: Variant; var arg6: Variant; var arg7: Variant;
var arg8: Variant; var arg9: Variant; var arg10: Variant;
var arg11: Variant; var arg12: Variant; var arg13: Variant
😞 integer ; stdcall; external 'wrun32.dll';

then i fill in some values in a form, initialize the rts and call AcuCall like this:

param1:='00100000XXXXX';
resultat:=AcuCall('my_prog.acu',
param1,
{ noparam, is a null variant }
noparam,
noparam,
noparam,
noparam,
noparam,
noparam,
noparam,
noparam,
noparam,
noparam,
noparam,
noparam,
noparam,
);


this starts the debugger with my program. the code looks something like this: (simplified)
01 LNK-AREA.
05 LNK-FTGNR PIC 9(3).
05 LNK-ENHETSNR PIC 9(5).
05 LNK-ANVANDARE.
07 LNK-ANVANDAREN PIC X(5).
LINKAGE SECTION.
77 call-variant usage handle.

Procedure division using call-variant.

call "C$GETVARIANT" using call-variant, lnk-area
giving result-code
string result-code delimited by size into kod
display MESSAGE kod title "kod"

* this box displays the return code, at present it is -2147352568, and the receiving field is as empty as ever.

Any hints or errors , feel free to point me in the right direction and give me a push....

Should i use another variant type in delphi, or not a variant at all.? Iam a bit lost and still a newbie!
0 Likes
5 Replies
Highlighted
Absent Member.
Absent Member.

RE: [archive] delphi and wrun32.dll

Originally posted by bernte
I wonder if anyone successfully tried calling the runtime dll from delphi code?


Here is a Delphi example:

unit wrun32u;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type AcuInitialize = function (cmd : PChar):integer; stdcall;
type Variantp = ^Variant;
type AcuCall = function (appname : PChar; p1, p2, p3, p4, p5, p6, p7, p8, p9,
     p10, p11, p12, p13, p14 : Variantp):integer; stdcall;
type AcuShutdown = function ():integer; stdcall;
type AcuExitCode = function (pBuf : PChar; iBufSize : integer):integer; stdcall;
type AcuRetCode = function ():integer; stdcall;
type PInteger = ^Integer;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
  Lib : THandle;
  acme : THandle;
  CallRes : LongInt;
  AcuInit : AcuInitialize;
  AcuRun : AcuCall;
  AcuEnd : AcuShutdown;
  AcuExit : AcuExitCode;
  AcuRet : AcuRetCode;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
Var Nullv : Variant;
    Nullp : Variantp;
    MyBuf : Array [0..1023] of Char;
    tst : LongInt;
begin
  Nullv := '';
  Nullv := VarAsType(Nullv, varNull);
  Lib := LoadLibrary('c:\acucorp\acucbl620\acugt\bin\wrun32.dll'#0);
  acme := LoadLibrary('acme.dll'#0);
    @AcuRet := GetProcAddress(acme,'Astdlib_return_code');
    If not Assigned(@AcuRet) Then
    Begin
     FreeLibrary(Lib);
     ShowMessage('Finner ikke retcide');
     Exit;
    End;
  If Lib
  begin
      ShowMessage('Finner ikke WRun32.dll!');
    Exit;
  end;    // if
  try
    @AcuInit := GetProcAddress(Lib,'AcuInitialize');
    If not Assigned(@AcuInit) Then
    Begin
     FreeLibrary(Lib);
     ShowMessage('Finner ikke AcuInitialize');
     Exit;
    End;

    @AcuRun :=  GetProcAddress(Lib,'AcuCall');
    If not Assigned(@AcuRun) Then
    Begin
     FreeLibrary(Lib);
     ShowMessage('Finner ikke AcuRun');
     Exit;
    End;

    @AcuEnd :=  GetProcAddress(Lib,'AcuShutdown');
    If not Assigned(@AcuEnd) Then
    Begin
     FreeLibrary(Lib);
     ShowMessage('Finner ikke AcuShutdown');
     Exit;
    End;

    @AcuExit:=GetProcAddress(Lib, 'cobol_exit_code');
    If not Assigned(@AcuExit) Then
    Begin
     FreeLibrary(Lib);
     ShowMessage('Finner ikke cobol_exit_code');
     Exit;
    End;

    CallRes := AcuInit('-c cblconfig'#0);
    If (CallRes <> 0) Then
    Begin
     FreeLibrary(Lib);
     ShowMessage('Feil etter kall til AcuInitialize('+IntToStr(CallRes)+')');
     Exit;
    End;

    Nullp := @Nullv;
    CallRes := AcuRun('calltst.acu'#0,Nullp,
                      Nullp,Nullp,Nullp,Nullp,Nullp,
                      Nullp,Nullp,Nullp,Nullp,Nullp,Nullp,Nullp,Nullp);

    if (CallRes <> 0) then
        ShowMessage('RuntimeError = ' + IntToStr(CallRes));

    CallRes := AcuExit(@MyBuf, sizeof(mybuf));
    tst := AcuRet();
    CallRes := PInteger(tst)^;

//    if (CallRes <> 0) then
        ShowMessage('ExitCode = ' + IntToStr(CallRes) + #13 + MyBuf);
  finally
    AcuEnd();
    FreeLibrary(Lib);
    end;    // finally
end;


[\CODE]

Note that this is how linkage section and procedure division should be set up (this example does not relate to the delphi code above, however...

[CODE]
       LINKAGE SECTION.

       77  VARIANT-NUM                         USAGE HANDLE.
       77  VARIANT-STR                         USAGE HANDLE.
       77  VARIANT-LONG-NUM                    USAGE HANDLE.
       77  VARIANT-FLOAT                       USAGE HANDLE.

       PROCEDURE DIVISION USING VARIANT-NUM, VARIANT-STR,
           VARIANT-LONG-NUM, VARIANT-FLOAT.
       MAIN-LOGIC.

      * Move the Variant data into COBOL items

           CALL "C$GETVARIANT" USING VARIANT-NUM,      TEST-NUM.
           CALL "C$GETVARIANT" USING VARIANT-STR,      TEST-STR.
           CALL "C$GETVARIANT" USING VARIANT-LONG-NUM, TEST-LONG-NUM.
           CALL "C$GETVARIANT" USING VARIANT-FLOAT,    TEST-FLOAT.


Hope this helps.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] delphi and wrun32.dll

oh yes... a pointer to the variant. Thanks a lot for this example. I will give it a try right on!

--

Stockholm Feb 4, 2005 +2C and cloudy
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] delphi and wrun32.dll

If you happen to be using C++ Builder, there is an even easier way. With Borland's implib utility, you can create Borland compatibile static link libraries and link directly to the runtime dlls. Then you can just add the libraries to your project and craete headers for the routines you would like to call.

Normally you will only want to link to wrun32.dll. If your C++ program is called from a cobol app, you do not even have to initialize the runtime.

here is an example:
extern "C"
{
int __stdcall cobol(char *name, int num_params, Argument *params);
}

now you can call AcuCorp library routines without manually loading the dll.

Merlin
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] delphi and wrun32.dll

Still trying, well after a small break anyway..

I have tried a number of variants and their handles now but C$GETVARIANT still returns -2147352568 (BAD_VARIABLE_TYPE) What exactly is bad? Is it my receiving cobol field ( PIC X(25)? is it the wrong type of variant i am referencing from delphi?

I use only one parameter, which i fill into text field 3 in the delphi form, normally containing the word "test" , the rest are null variants.

here is some code, the delphi bit closely follows Gisle's (above).


{Delphi 7 , Acucobol 6.2.0}
  type AcuCall = function( Name: Pchar; arg0, arg1, arg2, arg3, arg4,
                   arg5, arg6, arg7, arg8, arg9, arg10, arg11,
                   arg12, arg13: variantp
                   😞 integer ; stdcall;
....
var
resultat :integer;
param_1:pchar;
Switches,ProgramName:pchar;
Name,pv :variant;
noparam,param1:variantp;
length_s,length_c,length_p :byte;
....

  length_p:=edit2.GetTextLen;
  inc(length_p);
  getmem(param_1, length_p);
  edit2.GetTextBuf(param_1, length_p);
  Name:=StrPas(param_1);
  Name:=VarAsType(Name,VarString);
  param1:=@Name;

  resultat:=AcuRun(ProgramName,
                    param1,
                   {    noparam, a null variant  }
                    noparam,  ......

COBOL

       IDENTIFICATION              DIVISION.
       PROGRAM-ID. testform.
       ENVIRONMENT                 DIVISION.
       CONFIGURATION               SECTION.
       SPECIAL-NAMES.
           DECIMAL-POINT IS COMMA.
       DATA                        DIVISION.

       WORKING-STORAGE             SECTION.
       77 linkstring       PIC  X(25).
       01 result-code      PIC  s9(18).
       01 kod  PIC  X(24)
                  VALUE IS space.
       COPY "acugui.def".
       COPY "acucobol.def".
       COPY "crtvars.def".
       COPY "showmsg.def".
       LINKAGE                     SECTION.

        77 call-variant usage handle of variant.
       PROCEDURE DIVISION USING CALL-VARIANT.     
            call "C$GETVARIANT" using
               call-variant, linkstring
                          giving result-code
                 string result-code delimited by size into kod
           display MESSAGE kod title "kod".


 
       COPY "showmsg.cpy".

(in the delphi code, pchar look like a smiley followed by char )
Not exactly rocket science but we will probably get there 🙂

In another example, when i don't use parameters, the cobol program work fine, but it doesent show any images on bitmap buttons or any kind of embedded icons... why ?


Bernte
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] delphi and wrun32.dll

Try changing this:

        77 call-variant usage handle of variant.


to this:


        77 call-variant usage handle.


That might do.

Apart of that, I'd like to say that we with 7.0.0 has introduced a completely new, more standardized interface, if you are heading in that direction I would strongly suggest you look at that instead. We have a Delphi example there as well.
0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.