Jump to content

Recommended Posts

Posted

What reason could you have to believe it won't work? Have you even looked at the UDF code? A large number of them make calls to dlls by string name. They get loaded, called, unloaded.

I'm half tempted to irritate one of the developers just to get you to understand.

Posted

  trancexx said:

No, it doesn't work that way.

I've just checked the help file and it's basically saying the same thing. That is wrong.

Where are you getting this information from? There is no way AutoIt can determine what function belongs to a certain DLL without first loading the library (using LoadLibrary) and then calling GetProcAddress. There is one exception to this - the user passing a handle to the all ready loaded library (DllOpen). Maybe Windows does something weird when LoadLibrary is called, but LoadLibrary is called if you only pass a filename.

  Quote

If a dll filename is given then the DLL is automatically loaded and then closed at the end of the call. If you want to manually control the loading and unloading of the DLL then you should use DllOpen and DllClose and use a handle instead of a filename in this function.

Let's say you are calling a DLL from C++ (like AutoIt does each time DllCall is called):

const char *szFunctionName = "add";

How do we call the "add" function? How do we know which DLL it is in? You don't, unless you know what DLL it is in.

I think you are confused with DLLs and link libraries. When a C++ program, for example, links with user32.lib, that library file tells the compiler the address of the functions in user32.dll (the functions that are used, anyways). This is the only way what you are saying can work, and since AutoIt takes a dynamic string for the name of the function, this just can't work.

Posted

  cppman said:

Where are you getting this information from? There is no way AutoIt can determine what function belongs to a certain DLL without first loading the library (using LoadLibrary) and then calling GetProcAddress. There is one exception to this - the user passing a handle to the all ready loaded library (DllOpen). Maybe Windows does something weird when LoadLibrary is called, but LoadLibrary is called if you only pass a filename.

I'm observing and drawing conclusions. Call that what ever you want but that's the way I'm learning.

My observation on this is that when you pass a string (name of the dll) to DllCall() then it is not loaded using function

LoadLibrary but LoadLibraryEx with flag 0x00000001 - meaning that if you call some function from that dll that is relaying on some other function in some other not loaded dll your function will fail. Even more under some circumstances (pretty usual ones) there is a strong possibility that the script will crash. Loading it this way is almost as it's not loaded at all.

Passing dll name to DllCall() is safe only if you can retrive its module handle via function GetModuleHandle (

Kernel32.dll again). That would mean that that dll is "fully" loaded. You need DllOpen() for that.

Further more, since DllOpen() will call LoadLibrary (aha!) - or LoadLibraryEx with no flag (that is the same thing), it will cause some other dlls to be loaded as well. This means that if you are some jolly guy (well, you know...) you can load one dll and call from another just for fun.

This is ok:

DllOpen("some_dll")
DllCall("some_dll", ....)

It's very much not ok if you comment out first line.

  cppman said:

Let's say you are calling a DLL from C++ (like AutoIt does each time DllCall is called):

const char *szFunctionName = "add";

How do we call the "add" function? How do we know which DLL it is in? You don't, unless you know what DLL it is in.

Yes, of course.

  cppman said:

I think you are confused with DLLs and link libraries. When a C++ program, for example, links with user32.lib, that library file tells the compiler the address of the functions in user32.dll (the functions that are used, anyways). This is the only way what you are saying can work, and since AutoIt takes a dynamic string for the name of the function, this just can't work.

No, actually I think that some peoples are confused with DllCall() using handles because it reminds on FileWrite() and related functions.

What I wrote here, as I said, is drawn out of my observations and very well may not be true.

Nevertheless, I can show you examples that will confirm my writing if you want since we are way off-topic now.

@Richard Robertson

to irritate???

♡♡♡

.

eMyvnE

Posted

Yes irritate. It's a word. It means to annoy or bother. It's what you are doing to me.

I was saying I would hunt down a developer to get him to come and shut you up because the functionality described in the help file and in Chris's and my posts is how it works.

Posted (edited)

  Richard Robertson said:

Yes irritate. It's a word. It means to annoy or bother. It's what you are doing to me.

I was saying I would hunt down a developer to get him to come and shut you up because the functionality described in the help file and in Chris's and my posts is how it works.

Yes, you are right about that word. This is what I got on it:

Irritation, in biology and physiology, is a state of inflammation or painful reaction to allergy or cell-lining damage. A stimulus or agent which induces the state of irritation is an irritant. Irritants are typically thought of as chemical agents (for example phenol and capsaicin) but mechanical, thermal (heat) and radiative stimuli (for example ultraviolet light or ionising radiations) can also cause irritation.

That post of yours is saying a lot of you.

I'm sure that someone who knows how DllCall() really works would have no trouble beating what I wrote there since that being purely circumstantial and built on few cases of DllCall() failures. That would give us a chance to fully comprehend that aspect of AutoIt.

That someone apparently is not you.

Edited by trancexx

♡♡♡

.

eMyvnE

  • Administrators
Posted

  trancexx said:

I'm observing and drawing conclusions. Call that what ever you want but that's the way I'm learning.

My observation on this is that when you pass a string (name of the dll) to DllCall() then it is not loaded using function

LoadLibrary but LoadLibraryEx with flag 0x00000001 - meaning that if you call some function from that dll that is relaying on some other function in some other not loaded dll your function will fail. Even more under some circumstances (pretty usual ones) there is a strong possibility that the script will crash. Loading it this way is almost as it's not loaded at all.

LoadlibraryEx is not used. LoadLibrary() is used for for both DllCall(<string filename>) and DllOpen().

  Quote

This is ok:

DllOpen("some_dll")
DllCall("some_dll", ....)

It's very much not ok if you comment out first line.

They should be functionally identical. The only difference when you have both lines is that LoadLibrary("some_dll") ends up getting called twice (once for DllOpen and once again because of the string parameter in DllCall). Using DllCall() on it's own works fine but at the end of the call FreeLibrary() is called - if the reference count is 0 then the dll is then unloaded. DllOpen exists purely for removing the need for Loadlibrary to be called lots of times. For most system Dlls (kernel32, user32.dll, etc) this doesn't matter because they will have already been loaded by the system and future LoadLibrary calls are instant just increase the reference count, but for custom dll files that may have significant startup/shutdown code this can speed things up.

The only possible scenario I can imagine is causing you a problem is if you are relying on a custom dll to remain loaded between multiple DllCall(). By having the extra DllOpen call at the top of the script you are effectively artificially increasing the reference count of the Dll so that when you use the filename again in a DllCall it won't get unloaded (as the reference count will not be 0). Using DllOpen and then the handle in subsequent DllCalls would be more correct.

  Quote

No, actually I think that some peoples are confused with DllCall() using handles because it reminds on FileWrite() and related functions.

DllOpen handles and File handles are the same - they are just a number that AutoUt uses internally to retrieve a previous DllOpen handle.


 

Posted

  Jon said:

For most system Dlls (kernel32, user32.dll, etc) this doesn't matter because they will have already been loaded by the system and future LoadLibrary calls are instant just increase the reference count, but for custom dll files that may have significant startup/shutdown code this can speed things up.

Doesn't this mean that the optional parameter in _IsPressed() is not necessarily?

Broken link? PM me and I'll send you the file!

Posted (edited)

  Jon said:

The only possible scenario I can imagine is causing you a problem is if you are relying on a custom dll to remain loaded between multiple DllCall(). By having the extra DllOpen call at the top of the script you are effectively artificially increasing the reference count of the Dll so that when you use the filename again in a DllCall it won't get unloaded (as the reference count will not be 0).

Yes, that's it! I was having problems with opengl32.dll (and related), msvfw32.dll and winhttp.dll caused by that (they must not get unloaded while working with them). Last one tend to crash things if unloaded.

Thanks for that post and light coming out of it.

Consider your self to be owned by herewasplato a drink (herewa, don't play like you don't know what I mean)

Edited by trancexx

♡♡♡

.

eMyvnE

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...