Highlighted
Absent Member.
Absent Member.
3352 views

[archive] Calling .dll via Thin Client -completely lost

[Migrated content. Thread originally posted on 03 August 2006]

Hello,

If I have understood correctly it is possible to call Windows DLLs on the client side (from applications located on a Linux-server) through TC.

I have no experience whatsoever about C-data types or Windows API or .dlls, but since I have been fiddling with Thin Client lately, I gave it a try just for the heck of it.

I thought it would be wise to start with something simple, like placing some text on the clipboard. Now I have been stuck with this for days, and have no idea where I'm going wrong but I have a strong feeling it's something fundamental. It would be no surprise since I'm wondering on a totally strange territory.

It seems to me, that the call to memcpy isn't getting anything done. All I can get to the clipboard is a few symbols, it doesn't matter if I call memcpy or not.

Could somebody here give me a few pointers to guide me to the right direction? Or maybe handles???

Sample code as an attachment...
0 Likes
13 Replies
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

I would not say you picked the easiest example... Dealing with external memory allocation is rather complex in itself, using it with Thin Client makes it no easier.

For testing DLL in the context of Thin Client, I would rather suggest you try use the function GetSystemMetrics (see msdn for all that this function can do).

Let us say you would like to check how many buttons the mouse have:

77 nIndex PIC X(4) COMP-N.
77 NoOfButtons PIC X(4) COMP-N.
..
PROCEDURE ...
...
CALL "@[DISPLAY]:USER32.DLL@WINAPI".
MOVE 43 TO nIndex.
CALL "GetSystemMetrics" USING
BY VALUE nIndex GIVING NoOfButtons.
CANCEL "USER32.DLL".
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

Hi Gisle,

First of all, thank you for all the information I have found reading your posts. They have been a great help finding out new ways to use Acucorp's products when developing ours.

Well, I kind of got the feeling this wasn't as straightforward as I thought. Can you try to explain where the problem lies and if it is possible to solve? Are there some restrictions concerning memory allocation when working with TC and DLLs?

I can, of course, try to do other things with DLLs but if I leave this unsolved now, it'll be waiting around the corner for sure.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

Your problem is probably with external memory. Because you use out of ACUCOBOL-GT tools to allocate memory, the runtime has no way of knowing the size of the dynamic memory. Which is cruical when it comes to thin client due to the need of sending data back and forth.

There are two ways to deal with this, the WITH SIZE phrase and the compiler switch -Zm.

I suggest you read about those.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

Already done that. I have been using the -Zm option when compiling, but it did not make any difference.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

How about the WITH SIZE phrase then?

Here are some clues:

First, change your syntax so that you do not use DLL-CONVENTION, it is easy to get lost in that, instead apply @WINAPI suffix to the calls to the user32.dll and kernel32.dll like:

CALL "@[DISPLAY]:user32.dll@WINAPI"
CALL "@[DISPLAY]:kernel32.dll@WINAPI"
CALL "@[DISPLAY]:msvcrt.dll"

Note that msvcrt.dll shall not have the WINAPI suffix.
Second;

When you copy from a working storage variable to the clipboard, there is no need for the stuff you do with malloc. Here is what you have to do to copy a working storage item to the global handle:

           CALL    "GlobalLock"     USING
                   BY VALUE         GLB-PTR
                   GIVING           MEM-PTR
                   ON EXCEPTION     GO TO ERR-CALL.

           IF      MEM-PTR          = 0
                   CALL             "CloseClipboard"
                                    ON EXCEPTION CONTINUE
                                    END-CALL
                   GO               TO ERR-CALL.

           CALL    "memcpy"         USING
                   BY VALUE         MEM-PTR
                   BY REFERENCE     CMD-LINE
                   BY VALUE         VAR-SIZE
                   ON EXCEPTION     GO TO ERR-CALL.

           CALL    "GlobalUnlock"   USING
                   BY VALUE         GLB-PTR
                   ON EXCEPTION     GO TO ERR-CALL.

           CALL    "SetClipboardData" USING
                   BY VALUE         CF-TEXT
                   BY VALUE         GLB-PTR
                   ON EXCEPTION     GO TO ERR-CALL.

           CALL    "CloseClipboard"
                   ON EXCEPTION     GO TO ERR-CALL.


This should give you a start.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

Thank you for the tip, I have not seen this @WINAPI -suffix in any examples or anywhere in the Acucorp's documentation. It certainly is clearer than changing the DLL-CONVENTION back and forth.

I started to use M$ALLOC after I had been struggling for a while and read this text about calling DLLs with Thin Client (AcuConnect User's Guide, ver 6.2, section 6.5.6.3):

"Passing a pointer as a parameter of a DLL call that executes on the display host requires some special handling in code, because the pointer value refers to a memory address on the application host. In certain cases, you may safely pass a pointer BY VALUE. You may never pass a pointer BY REFERENCE.".

I guess this could also mean that you shouldn't pass a reference to a pointer-value of a data item as a pointer, but first thing that came my mind when reading this was that you shouldn't pass a reference to a data-item as a pointer (isn't that what you actually do when using the BY REFERENCE -frase?) when using Thin Client. The text does seem a bit unclear to me, but maybe it's just my skills in english.

I'm sorry, but the example you gave didn't help. I tried passing the pointer by using the BY REFERENCE-frase again and all the other things I could imagine would make a difference, but with no success.

Before I even thought about posting a question here, I had read every example concerning DLLs at your site and all the documents yuo have on the subject. Would it be possible for you to make an working example that moves some text on the clipboard and post it in full length here? It would mean a great deal for me, because from that I could easily see what I'm doing wrong. It propably would help others as well in the future. It should be only a few lines of code when you know what your doing. Sorry for bugging you with this, but I'm getting a bit desperate with this.

P.S. I found an error in the example I posted. I'm giving MEM-PTR instead of MEM-HNDL to GlobalUnlock. Fixing this did not help.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

I have not seen this @WINAPI -suffix


Just note that it is not supported in 6.2 I believe this feature came with 7.0.0, so you would have to use 7.0.0 or later to benefit from this feature.

I guess this could also mean that you shouldn't pass a reference to a pointer-value of a data item as a pointer


Yes and no. In most cases, when you have allocated memory, this is already referenced as you point out. Thus, when passing the address you would use BY VALUE on a pointer. In some cases though, you are expected to pass the address of an address, in which case you would use a BY REFERENCE on a pointer as well. Confused? It is difficult, but there is a system in it. However, explaining this here is way beyond the scope of this forum, if you are working on more Windows programming beyond what is basic with the runtime, you really should attend our Advanced Windows course taking place worldwide this fall. Check out http://www.acucorp.com/events for locations near you.

Would it be possible for you to make an working example


I cannot produce examples for every single case here, I am sure you understand that. What I can do, is to show an example when I have a generic one available. Which I happen to have in this case (attached), but if that doesn't help you, you can contact Acucorp support and ask for assistance from our professional services.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

We are running version 7.2 on our Thin Client testbed, so there was no problem using @WINAPI-suffix.

Thanks for the example, I will get into that. If it doesn't help, I guess I will just have to find assistance through different channels.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

I must say, I never stop suprising myself with my stupidity. Or in this case to be exact, illiteracy.

The problem was missing BY VALUE -phrase in the CALL statement when trying to pass the handle to GlobalLock-fuction. And when the default is BY REFERENCE, I ended up passing the pointer to the handle.

Here is a working version of the example, maybe some other poor beginner might find some help from it. After all, there aren't that many TC-DLL-examples laying around for us. There is no exception handling or anything else fancy, but it does the trick with Thin Client.

I did remove the unnecessary M$ALLOC-M$PUT-M$FREE operations and pass the pointer to the text using BY REFERENCE-phrase instead. I also started to use the @WINAPI -suffix instead of changing the DLL_CONVENTION back and forth. Thanks to Gisle, I won't be doing these unnecessary moves in the future. And thanks for the example, with that I could see I was doing everything right in principal and eventually found my mistake.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

Good to hear you found the problem, the devil is in the details. 🙂
Thank you for contributing to the forum with this example.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling .dll via Thin Client -completely lost

I am using the following to call in my program....

CALL "@[DISPLAY]:KERNEL32.DLL@WINAPI".

and still getting program not found or inaccessible errors. I have tried it as Kernel32.dll, Kernel32.DLL and kernel32.dll (as well as mixing the display and winapi text upper and lower) with out any luck.

I have been looking at other posts and the manuals, but can't seem to find anything else to help on this. Someone suggested to me that there may be an issue in our config file that may need to be changed to allow both upper and lower case.

If anyone has any other questions or thoughts on this, I'd appreciate the feedback.
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.