Highlighted
Super Contributor.
Super Contributor.
3713 views

Load a DLL

Jump to solution

Good morning, I'm needing to load a dll and I find nothing in Cobol for this, but I found the instructions in VB

 <DllImport("c:SATSAT.dll", CallingConvention := CallingConvention.Cdecl)> _
Public Function AtivarSAT(numeroSessao As Integer, subComando As Integer, codigoDeAtivacao As String, CNPJ As String, cUF As Integer) As IntPtr
End Function

How to do this in Cobol? And the dll is in 32bit and my OS is 64. I need to change something in my project. thank you.

0 Likes
1 Solution

Accepted Solutions
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: Load a DLL

Jump to solution

The error that you are seeing is caused by calling a native .dll that is a different bitism than the calling managed program.

If this is a 32-bit .dll that you are calling then the managed code project must be built as type x86 and not x64 or anyCPU.

It is unclear from your description what call you are actually trying to make.

You show the following call statement:

   call "Bematech_FI_ProgramaHorarioVerao"                                      

        returning cmdstatus.

but the function signature that you show does not match that call. It is instead trying to call a function called TrocarCodigoDeAtivacao which takes a number of parameters and returns a native pointer:

char * TrocarCodigoDeAtivacao (

int numeroSessao;

char * codigoDeAtivacao;

int option;

char * novoCodigo;

char * confNovoCodigo

);

If you are trying to call TrocarCodigoDeAtivacao then you should be able to call it like you did in NX native code but because it returns a native pointer you will have to perform a couple of extra steps in order to marshal this into managed memory. The following is an example of how to copy the bytes pointed to by the native pointer into managed code. I didn't know how you had this defined so I guessed.

$set ilusing"System.Runtime.InteropServices"

01 numeroSessao  pic s9(9) comp-5.

01  codigoDeAtivacao pic x(100).

01 option pic s9(9) comp-5.

01 novoCodigo pic x(100).

01 confNovoCodigo pic x(100).

01 pData type Byte occurs any.

01 _pDataBlock      type IntPtr

01 ret-params.

    05 field1   pic x(2).

    05 field2  pic 9(5).

   call winapi "TrocarCodigoDeAtivacao"

      using by value numeroSessao

               by reference codigoDeAtivacao

               by value  option

               by reference novoCodigo.

                                    confNovoCodigo

      returning _PDataBlock

   end-call

   set size of pData to length of ret-params

   invoke type Marshal::Copy(_pDataBlock, pData, 0, LENGTH OF ret-params)

   set ret-params to pData    

...

View solution in original post

0 Likes
6 Replies
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: Load a DLL

Jump to solution

Hello,

Is it native or managed DLL?

Regards,

–Ғɑɳօ
0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: Load a DLL

Jump to solution

If you are calling a native .dll from a managed .NET program then you are using a platform invoke or p/invoke. This is covered in the docs here: In Visual COBOL the hard work is done under the covers so you can call a native .dll from managed code using the standard COBOL CALL statement just like you would call it from native code COBOL. This includes 3rd party .dlls or Windows API's.

If the native .dll is in 32-bit then the managed project must be set to x86 so that it too will be generated as 32-bit. This will then run on both a 32-bit OS and a 64-bit OS.

You will need to add a reference to the 32-bit .dll within your managed project.

0 Likes
Highlighted
Super Contributor.
Super Contributor.

RE: Load a DLL

Jump to solution

I will try to explain what happens. Here in Brazil we have to do tax changes and the government unified the sending of information and he is using this dll, I made another program NetExpress and the call went like this:       

special-names.           

call-convention 74 is winapi.       

procedure division.           

set aPointer to entry "BemaFI32.dll".           

call "Bematech_FI_ProgramaHorarioVerao"                                       

returning cmdstatus.

But in Visual Cobol not know how to do. Dll in this manual instruction is as follows:

char * TrocarCodigoDeAtivacao (

int numeroSessao;

char * codigoDeAtivacao;

int option;

char * novoCodigo;

char * confNovoCodigo

);

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: Load a DLL

Jump to solution

The same call code that you used under Net Express should work in a managed COBOL program as well including the call-convention, etc.

To make the native code .dll available for the call you can either add a reference to it in your managed code project by right-clicking on the references folder, selecting Add Reference and then browsing to the location and selecting the .dll or by adding in the Project Properties-->COBOL tab the directive ilpinvoke"dllname" where "dllname would be the full location and name of your dll.

If this does not work then please show me the error that you are receving.

Thanks

0 Likes
Highlighted
Super Contributor.
Super Contributor.

RE: Load a DLL

Jump to solution

Using the same format NetExpress of the following error:

{"% d error message text not found \ n (Could not load file or assembly 'file: /// c: \\ \\ sat SAT.dll.' or one of its dependencies The module should contain an assembly manifest .) "}

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: Load a DLL

Jump to solution

The error that you are seeing is caused by calling a native .dll that is a different bitism than the calling managed program.

If this is a 32-bit .dll that you are calling then the managed code project must be built as type x86 and not x64 or anyCPU.

It is unclear from your description what call you are actually trying to make.

You show the following call statement:

   call "Bematech_FI_ProgramaHorarioVerao"                                      

        returning cmdstatus.

but the function signature that you show does not match that call. It is instead trying to call a function called TrocarCodigoDeAtivacao which takes a number of parameters and returns a native pointer:

char * TrocarCodigoDeAtivacao (

int numeroSessao;

char * codigoDeAtivacao;

int option;

char * novoCodigo;

char * confNovoCodigo

);

If you are trying to call TrocarCodigoDeAtivacao then you should be able to call it like you did in NX native code but because it returns a native pointer you will have to perform a couple of extra steps in order to marshal this into managed memory. The following is an example of how to copy the bytes pointed to by the native pointer into managed code. I didn't know how you had this defined so I guessed.

$set ilusing"System.Runtime.InteropServices"

01 numeroSessao  pic s9(9) comp-5.

01  codigoDeAtivacao pic x(100).

01 option pic s9(9) comp-5.

01 novoCodigo pic x(100).

01 confNovoCodigo pic x(100).

01 pData type Byte occurs any.

01 _pDataBlock      type IntPtr

01 ret-params.

    05 field1   pic x(2).

    05 field2  pic 9(5).

   call winapi "TrocarCodigoDeAtivacao"

      using by value numeroSessao

               by reference codigoDeAtivacao

               by value  option

               by reference novoCodigo.

                                    confNovoCodigo

      returning _PDataBlock

   end-call

   set size of pData to length of ret-params

   invoke type Marshal::Copy(_pDataBlock, pData, 0, LENGTH OF ret-params)

   set ret-params to pData    

...

View solution in original post

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.