Discussion:
[OT?] Borlands Tasm32 syntax for calling a function in a specific DLL.
(too old to reply)
R.Wieser
2022-07-19 15:36:23 UTC
Permalink
Hello all,

I'm using Borlands Tasm32 (v5.0) and just ran into a situation where I had
to call 'DllGetVersion' inside ComCtl32. The problem is that that function
exists in several other DLLs (shell32 to name another).

IOW, although I can write 'call DllGetVersion, ...' I never know which DLL
will actually get called.

My question:

Does anyone here know if Tasm32 knows an assemble-time syntax to call a
function from a specific DLL ? (would be handy for a few other functions
too)

Remarks:

I currently used the runtime "LoadLibary", "GetProcAddress" solution, but
thats cumbersome.

I could also rename the function itself (from "DllGetVersion" to something
like "ComCtl32_GetVersion") and rebuild the libarary, but thats a ... well,
not a solution I'd really like either.

Regards,
Rudy Wieser

P.s.
Anyone knows where I can find ComCtl32 v6.x ?
Frank Kotler
2022-07-20 01:50:38 UTC
Permalink
Post by R.Wieser
Hello all,
Hi Rudy,
Seems on-topic to me.

Best,
Frank
Post by R.Wieser
I'm using Borlands Tasm32 (v5.0) and just ran into a situation where I had
to call 'DllGetVersion' inside ComCtl32. The problem is that that function
exists in several other DLLs (shell32 to name another).
IOW, although I can write 'call DllGetVersion, ...' I never know which DLL
will actually get called.
Does anyone here know if Tasm32 knows an assemble-time syntax to call a
function from a specific DLL ? (would be handy for a few other functions
too)
I currently used the runtime "LoadLibary", "GetProcAddress" solution, but
thats cumbersome.
I could also rename the function itself (from "DllGetVersion" to something
like "ComCtl32_GetVersion") and rebuild the libarary, but thats a ... well,
not a solution I'd really like either.
Regards,
Rudy Wieser
P.s.
Anyone knows where I can find ComCtl32 v6.x ?
George Neuner
2022-07-21 12:13:06 UTC
Permalink
On Tue, 19 Jul 2022 17:36:23 +0200, "R.Wieser"
Post by R.Wieser
I'm using Borlands Tasm32 (v5.0) and just ran into a situation where I had
to call 'DllGetVersion' inside ComCtl32. The problem is that that function
exists in several other DLLs (shell32 to name another).
Does anyone here know if Tasm32 knows an assemble-time syntax to call a
function from a specific DLL ? (would be handy for a few other functions
too)
I currently used the runtime "LoadLibary", "GetProcAddress" solution, but
thats cumbersome.
Sorry, I never used Tasm (any version), but WRT to GetProcAddress I
don't believe there is any other way to guarantee you will get the
right function.

One suggestion though:

If you know the DLL is already resident - because you static linked or
already have loaded it dynamically - you should use GetModuleHandle
instead of LoadLibrary. Calls to LoadLibrary must be paired with
calls to FreeLibrary because they maintain usage reference counts on
the loaded module. If you don't pair them properly, modules can end up
either prematurely unloaded or locked into memory.
Post by R.Wieser
Regards,
Rudy Wieser
P.s.
Anyone knows where I can find ComCtl32 v6.x ?
https://www.dll-files.com/comctl32.dll.html
Look near the bottom of the page for 6.x

Hope this helps.
George
R.Wieser
2022-07-21 13:43:03 UTC
Permalink
George,
Post by George Neuner
Sorry, I never used Tasm (any version), but WRT to GetProcAddress
I don't believe there is any other way to guarantee you will get
the right function.
There is, and I mentioned it just below the 'GetProcAddress' method.
Post by George Neuner
If you know the DLL is already resident you should use GetModuleHandle
instead of LoadLibrary.
Does it make a difference ? (whats the 'should' about ?)

Regards,
Rudy Wieser
George Neuner
2022-07-21 15:55:30 UTC
Permalink
On Thu, 21 Jul 2022 15:43:03 +0200, "R.Wieser"
Post by R.Wieser
George,
Post by George Neuner
Sorry, I never used Tasm (any version), but WRT to GetProcAddress
I don't believe there is any other way to guarantee you will get
the right function.
There is, and I mentioned it just below the 'GetProcAddress' method.
Yes, but it involved recompiling the module. Most people are not in a
position to rebuild system DLLs, so that isn't a general solution.
Post by R.Wieser
Post by George Neuner
If you know the DLL is already resident you should use GetModuleHandle
instead of LoadLibrary.
Does it make a difference ? (whats the 'should' about ?)
'should' means it is the best choice ... at least under the given
circumstances.


And it does make a difference, which I explained previously and will
expound on now:


LoadLibrary manipulates reference counts on the loaded module and
every call to LoadLibrary has to be paired with a call to FreeLibrary.
Unbalanced calls to LoadLibrary can cause a shared DLL to end up
locked into memory.
[Note that application exit automatically calls FreeLibrary for all
DLLs attached to the process. So application exit will balance one
LoadLibrary call for any given library.]

GetModuleHandle just searches for an already loaded module and returns
a handle to it (that can be passed to GetProcAddress).


If you are dealing with an already loaded DLL (for which you don't
have a handle available), you have to do one of the following:
(in C)

hnd = GetModuleHandle( "ComCtl32" );
ptr = GetProcAddress( hnd, "DllGetVersion" );

or

hnd = LoadLibrary( "ComCtl32" );
ptr = GetProcAddress( hnd, "DllGetVersion" );
FreeLibrary( hnd );

Whenever you call LoadLibrary, you also have to call FreeLibrary
UNLESS you are deliberately loading a /new/ DLL and intend it to
remain resident until application exit. And if you do deliberately
load something, you 'should' (best practice) save the returned handle
because it is simpler than having to discover it again later.


I realize the documentation[1,2] says application exit frees libraries
regardless of reference counts ... but "free" in this case means
"detached from your process" and it does not necessarily mean the
library can or will be be unloaded from memory. In particular, if the
library instantiates one or more COM objects based on LoadLibrary
calls (which in general you can't know), and those loads are not
balanced by FreeLibrary calls, the library will never be unloaded (ie.
it will be locked into memory).

NB: DLLs in Windows can have their own private heaps not associated
with any client process. Objects created on a private heap on behalf
of a client process might be able to survive the termination of that
process. COM objects have their own reference counts which are
unrelated to reference counts on the module that implements them.
Windows will not unload any module that still has live COM objects.

To be safe you need to make sure you always balance explicit
LoadLibrary calls with FreeLibrary calls.
Post by R.Wieser
Regards,
Rudy Wieser
Hope this helps.
George

[1]
https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya
[2]
https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-freelibrary
R.Wieser
2022-07-22 08:56:31 UTC
Permalink
George,
Post by George Neuner
Post by R.Wieser
Post by George Neuner
I don't believe there is any other way to guarantee you will get
the right function.
There is, and I mentioned it just below the 'GetProcAddress' method.
Yes, but it involved recompiling the module.
So there /is/ a way, but you do not like it. Thats something quite
different.
Post by George Neuner
Most people are not in a position to rebuild system DLLs,
Whut ? Who has said anything about rebuilding *DLLs* ? (library, not DLL)
Post by George Neuner
so that isn't a general solution.
I can't remember having said anything about it needing to work for everyone
else too ...

But yes, that is why I posted "not a solution I'd really like either" -
*even though* I wager to guess that I'm the only one here who uses Borlands
Tasm32 v5.x ....

Regards,
Rudy Wieser

Loading...