Highlighted
Super Contributor.
Super Contributor.
2421 views

Windows API calls from managed code

Jump to solution

I followed the instructions from this link:

http://community.microfocus.com/microfocus/cobol/visual_cobol/f/18/t/11460.aspx

I tried setting a procedure-pointer to the Windows libraries in order to load them but I get error 173 when executing the set procedure pointer statements.

For example:  set pp to entry "kernel32.dll".

I had to set up project references to the libraries in my SysWOW64 folder.  Does anyone know why setting a procedure-pointer isn't working?

This happens even if I include SywWOW64 in the path.

Phil Levin

0 Likes
1 Solution

Accepted Solutions
Highlighted
Super Contributor.
Super Contributor.

RE: Windows API calls from managed code

Jump to solution

Your first suggestion produced no errors.  I really don't need to set a procedure pointer.  I only needed to add these lines to the top of the program:

     $set ilpinvoke"kernel32"

     $set ilpinvoke"gdi32"

Phil Levin

View solution in original post

0 Likes
7 Replies
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: Windows API calls from managed code

Jump to solution

Hi Phil,

You shouldn't get a 173 error on the set statement but you might get a 173 on the call of the WinAPI function if the .dll wasn't loaded correctly.

I just tested this here and although the set proc-pointer method used to work it no longer appears to in 2.3.2.

The recommended way to get these loaded now is actually to use the compiler directive ilpinvoke which is the same thing as adding a project reference but you only require the base name of the .dll and then the correct bitism will be loaded at run-time:

$set ilpinvoke"kernel32"

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: Windows API calls from managed code

Jump to solution

The set proc-pointer approach should work but you should add the $set noilnative directive to your program. When I add this to my example it will load kernel32 ok.

Please note that when you load a non-COBOL .dll such as kernel32.dll in this manner using managed code, the pointer variable might still be set to null even when it is successful. This is because it is looking for a main entry point with the same name as the .dll and if it doesn't exist it will be set to null. Therefore it is difficult to check if the load was successful prior to calling the actual function.

0 Likes
Highlighted
Super Contributor.
Super Contributor.

RE: Windows API calls from managed code

Jump to solution

After coding the following, the WinAPI call works although I get the exception below in my event log when I execute "SET MYPOINTER":

     $set noilnative

     $set ilpinvoke"kernel32"

     $set ilpinvoke"gdi32"

      01 MYPOINTER                            PROCEDURE-POINTER.

       SET MYPOINTER TO ENTRY "kernel32.dll"

"Could not load file or assembly 'file:///C:\windows\system32\kernel32.dll' or one of its dependencies. The module was expected to contain an assembly manifest."

Phil Levin

0 Likes
Highlighted
Super Contributor.
Super Contributor.

RE: Windows API calls from managed code

Jump to solution

Your first suggestion produced no errors.  I really don't need to set a procedure pointer.  I only needed to add these lines to the top of the program:

     $set ilpinvoke"kernel32"

     $set ilpinvoke"gdi32"

Phil Levin

View solution in original post

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: Windows API calls from managed code

Jump to solution

You should do either the $set ilpinvoke"kernel32" or the set proc-pointer statement but not both.

0 Likes
Highlighted
Super Contributor.
Super Contributor.

RE: Windows API calls from managed code

Jump to solution

"set ilpinvoke" was working for VC 2.3.1 but we just installed 2.3.2 and I now get this compile error:

"ILPINVOKE invalid or not allowed here".

So I removed the ilpinvoke set statements and added "set noilnative" and tried using a procedure pointer

to load kernel32.dll.  I also added a project reference to it in SysWOW64.  I'm now getting this exception when setting the procedure pointer:

System.BadImageFormatException

Could not load file or assembly 'file:///S:\V63\AWCBL\DEBUG\kernel32.dll' or one of its dependencies. The module was expected to contain an assembly manifest.

Even though I get an exception, the WINAPI calls work but I get a run time error when exiting our application:

"MgLoad has stopped working".  MgLoad is the managed driver for our application and is the first program called.

I would like to get the "set ilpinvoke" statement working again, like it did for VC 2.3.1.

Phil Levin

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: Windows API calls from managed code

Jump to solution

Hi Phil,

Please open up a support incident for this as ilpinvoke works fine for me here in 2.3 U2. It sounds as if your path has been corrupted or perhaps you inadvertently changed your project type from x86 to x64 or anyCPU?

Thanks.

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.