Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Safe limit size for EXE file in FVP9 1

Piotr Czekalski

Programmer
May 17, 2024
50
0
6
PL
Hi all.

I have 2 similar projects in VFP9. I would like to join them in one. I compiled them for a testing and the EXE file size was about 800 KB.

I would like to ask experienced colleagues. What is the safe limit size for EXE file in FVP9 ?
 
ERROR: shellexecute can not find entry point ....
"Cannot find entry point" occusr, if you declare a function in the wrong DLL. functions you DECLARE being in a DLL also are case sensitive. Declare ShellExecute and call shellexecute, you'd get the error file "shellexecute,prg" does not exist, so I assume you declare and call ShellExecute, but in the wrong DLL?

What happens then is that the DECLARE works, VFP simply believes there is such and such a function existing in the specified DLL, but when using it, it will actually look for the enry point (that's the address to call in that DLL) to call that function, and so you get a late error when actually making the function call and not already when you make the DECLARE. You could consider not to verify this at the stage of the DECLARE bad design, but that's what it is. Here's a simple demo that shows the error happens not already at the DECLARE of a non-existing function, but in first trying to call it:

Code:
Declare integer NonExistingAPIFunction In Kernel32.dll Integer
? NonExistingAPIFunction(0)

ShellExecute is defined within the shell32.dll, and it has to be ShellExecute, not shellexecute.
 
Last edited:
For finding correct declares, look into the Win32API project of VFPX on https://github.com/VFPX/Win32API/tree/master

Another way it goes wrong is by wrong capitalization:
Code:
DECLARE INTEGER shellexecute IN shell32;
        INTEGER hWindow, STRING lpOperation,;
        STRING lpFile, STRING lpParameters,;
        STRING lpDirectory, INTEGER nShowCmd

shellexecute(0,"open","my.exe")
This time not because of the wrong DLL, but the wrong capitalization of the function.
 
I mean the size of the RAM memory used
Of what, of a function declaration? Not much bytes, but the only way to get the error you have is with a wrong declaration that makes the call wrong. That's not a RAM problem.
Function declarations also don't count to memory variables and are not saved by SAVE TO, even less so RESTOREd, then.

So when you get such an error you have a wrong declaration, that has got nothing to do with memory nor SAVE TO and RESTORE. The current declarations you have are not shown with LIST MEMORY, they are shown with LIST DLLs. They also require RAM, but only a few bytes and the error you have doesn't tell anything about that, it says your declare is wrong.

One beautify of code to all lowercase can cause this problem, for example, when all your ShellExecute() calls become shellexecute() calls that therefore throw this error.

One more thing: You can use aliases, i.e. you can DECLARE ShellExecute in shell32.dll as shellexecute, but if beautify changes this to declare shellexecute in shell32.dll as shellexecute you'll get the error anyway, you can't choose the capitalization different than as it is in the DLL, you have to declare it as ShellExecute or calls to it fail, wether you use a function name alias or not.

The error message is very specific about that, look everywhere in your merged project how you declare ShellExecute, Don't quit searching after finding a correct declare, look for all declares because it's safe already from the error message you do have one wrong declaration that gets executed and used and causes that error. It's not a RAM problem at all.

To make a stronger point: VFP is not case sensitive, but DLLs are, their entry points give you no freedom of choice of upp/lower case, and while the error is thrown in the call of ShellExecute that missing entry point error points out a wrong declaration, at a totally different previously run line of code anywhere in your whole project, wherever you do your DLL declarations.
 
Last edited:
Ok, I understand. I will check correctness of capitalization in project. I probably used "shellexecute" or "Shellexecute" syntax somewhere in compiled part of project. Thank you very much Chris.:)
 
Last edited:
If you encounter the error LIST DLLs will show how you declared functions. It'll not point out where you made a wrong declaration, but it has to be in some source code, even if it's now in a module you built into an EXE, APP or VFP (COM) DLL and use that.

For example do this and you'll see LIST DLLs shows you what function you declared (and the upper/lower casing used) besides what alias name you used:
Code:
DECLARE INTEGER ShellExecute IN shell32 as ShallExecute;
        INTEGER hWindow, STRING lpOperation,;
        STRING lpFile, STRING lpParameters,;
        STRING lpDirectory, INTEGER nShowCmd
List Dlls

results in
Code:
Declared DLLs:
ShellExecute              ShallExecute              c:\windows\system32\shell32.dll
So you see whether you made a case error in the first column, the name as it has to be found in the DLL, and can see by which alias name you decalred it, here Shall instead of Shell to demonstrate the difference.

No matter where that error is in your sources, it is not an error of shell32.,dll, it is in some VFP DECLARE call, no doubt about that.

Even if you use
Rich (BB code):
DECLARE INTEGER shellexecute IN shell32 as ShellExecute;
        INTEGER hWindow, STRING lpOperation,;
        STRING lpFile, STRING lpParameters,;
        STRING lpDirectory, INTEGER nShowCmd
Calling ShellExecute with the right capitalization of the alias name will error with the message "Cannot find entry point shellexecute in the DLL" because the alias name is translated with shellexecute as is the function name highlighted red. The only reason to give an alias name is for functions that have a name illegal in VFP, Windows API does not have such names, but third party DLLs could have. Anyway, shell32.dll includes ShellExecute, not shellexecute, nor Shellexecute, nor shellExecute, nor SHELLexecute nor ShElLeXeCuTe - only ShellExecute.
And no matter how hard you try to produce the error with correct function name but wrong alias names or anything else, you only get the error when you specify the red name wrong in some declare that runs before you make the call of the function to which the entry point in the DLL is not found. If you have that name right, even if you call the alias BONKERS, calls of BONKERS() will work. And calls of BoNKERS() would cause the error message "File 'bonkers.prg' does not exist." a comlpetely different error. So the error Connot find entry point tells you you 1. had a DECLARE, that 2. loaded the DLL function (actually created a definition/idea how VFP later would look up these calls and verify correct parameterizuation) and you 3. didn't and don't have a RAM problem with the DLL loaded being too large. So, really no RAM problem, clearly without any doubt just a DECLARE problem. You also don't get this error when there was a CLEAR DLL or CLEAR ALL, because it only comes up when there is a wrong declare.

And last not least, and what I also already mentioned, if you declare the right function name ShellExcute, but in the wrong DLL, that also causes the error:
Code:
DECLARE INTEGER ShellExecute IN kernel32;
        INTEGER hWindow, STRING lpOperation,;
        STRING lpFile, STRING lpParameters,;
        STRING lpDirectory, INTEGER nShowCmd
ShellExecute()
And as the error message then also is "Cannot find entry point ShellExecute in the DLL." it doesn't tell in which DLL, so you have to find the DECLARE that's wrong. LIST DLLS will then show that ShellExceiute was declared in kernel32.dll, the wrong dll. But without any doubt, the problem is in the DECLARE when that error message comes up, not in the call. It's just only revealed with the call as VFP does not verify the entry point when you do the DECLARE.
 
Last edited:
Do you know how to use Code References or GoFish for searching all your code for the culprit declare?
Just search for declare and let Code Rreferences list all your declare commands anywhere and then look in the result for shellexecute in wrong capitalization.

As you talked about code blocks you execute, the wrong declare could also come from there, of course. And once you get rid of the wrong declare, watch out that you can still have the wrong declare in place and active until you CLEAR DLLS or restart VFP. Even a new build doesn't remove active but wrong declarations from memory.
 
Last edited:

Part and Inventory Search

Sponsor

Back
Top