PowerBASIC Gazette

Number 112 www.powerbasic.com



July
Twenty-Seventh
2012

From: Bob Zale, President
           PowerBASIC, Inc.

To: PowerCODER

PowerBASIC Gazette #112
Subject: No more "MISSING EXPORT" Errors from your DLL's

Have you visited our web site lately? Lots of great new information for PowerBASIC Programmers. We've redesigned the Download Section. You can find what you need. You'll see Quick-Start tutorials, and much more! And the forums? Now more than 409,000 messages! We're closing in on a half-million messages from good programmers, just like you, on virtually every programming topic! Visit us now at www.powerbasic.com and be sure to leave a comment in the PowerForums!

But first, would you indulge me? Would you help us spread the word about PowerBASIC? You know, you are the world's best PowerBASIC advertisement. And every time we add a PowerBASIC customer, it helps us all. Every new user is an investment in the PowerBASIC future. How about it? Will you tell a friend about PowerBASIC? I hope so.

We'll make it easy for you to "Share the Power"! {smile} Anyway, here's the plan... You give us a name (or a few names), and we'll send just one short, informative e-mail. We'll never use the e-mail again, unless they choose to sign up. Share the Power! Just GOTO Share the Power You'll see the text of the message and add a contact name! The message is harmless, yet informative. And just think of the compilers we could build for you if everyone referred just one new PowerBASIC user!


Use "IMPORT ADDR" to avoid "MISSING EXPORT" Errors

Implicit Linking

By default, implicit (Load-time) linking is used for every Windows API Function declared in WIN32API.INC, and our other INC files. Implicit linking is used whenever a DECLARE includes a LIB/IMPORT clause, and the named function is used in the program. When your program is loaded, and before it actually starts running, Windows loads all the DLLs that are needed. However, if any of the DLLs aren't present, Windows produces a missing DLL error, and the program is terminated before it even gets started. This is the primary purpose of the LIB/IMPORT clause in the DECLARE statement.

Windows requires that every imported Sub/Function be precisely matched to an exported Sub/Function in the named DLL. If not, the program is immediately terminated, and the user is presented with a "Missing Export" error message. While implicit linking is by far the easiest way to call API functions, it presents some problems when your program calls functions that are only present in some versions of Windows.


Restricting the choice of platforms

For programs using features specific to WinXP and Win7, you can use the #OPTION VERSION5 metastatement. An attempt to run it on earlier platforms will produce a "new version of Windows required" error, rather than a cryptic "export" error message. This is better, but sometimes your programs will need to run on all versions of Windows. This can work, too, by just restricting some features on older operating systems.


Explicit Linking joins the fray

Missing Export errors are generated by Windows before the program ever starts running. So, using implicit linking, it just isn't possible to write a program which programmatically checks the Windows version to decide what it can call and what it must avoid. Luckily, we have explicit linking available, too.


LIB-Less DECLARE statements

The first step in explicit linking is to remove the LIB and ALIAS clauses from the DECLARE statement of the target API Subs and Functions. Next, we replace all direct calls to those Subs and Functions with a small piece of code that dynamically checks the availability of the API before calling it.

To achieve the first part, editing the WIN32API.INC file may seem the easiest route, but that comes with a small cost -- any changes made to that file will be lost if you install an updated version of the file in the future. The best solution is to copy the DECLARE statement directly into your program code. Then the LIB and ALIAS clause can be removed. Finally, to avoid conflicts with the older DECLARE, the function name is modified slightly to make it unique. This can be done since this new DECLARE acts purely as a template for the code we'll be using.

For example, let's look at the GetDiskFreeSpaceEx() API (which only became available in the OSR2 release of Windows 95). The original DECLARE looks like this:

DECLARE FUNCTION GetDiskFreeSpaceEx LIB "KERNEL32.DLL" ALIAS _
   "GetDiskFreeSpaceExA" (lpPathName AS ASCIIZ, _
   lpFreeBytesAvailableToCaller AS QUAD, _
   lpTotalNumberOfBytes AS QUAD, _
   lpTotalNumberOfFreeBytes AS QUAD) AS LONG

Using the above guidelines, our modified template DECLARE will look like this:

DECLARE FUNCTION tmp_GetDiskFreeSpaceEx (lpPathName AS ASCIIZ, _
   lpFreeBytesAvailableToCaller AS QUAD, _
   lpTotalNumberOfBytes AS QUAD, _
   lpTotalNumberOfFreeBytes AS QUAD) AS LONG

We used the prefix "tmp_" here to indicate that it is intended as a template function declaration only.


Dynamically check the target function

Windows offers built-in API functions to do the job. They work. They're complete. But they sure are tedious. Yes, there is an alternative in PowerBASIC... a very good alternative... but more about that later. First, let's consider the API scenario.

1- Since we removed the LIB clause from the new DECLARE, we have to instruct Windows to try to open the DLL that we know may contain the target API. In this case, it's KERNEL32.DLL, and and we load it like this:

LOCAL hLib AS DWORD
hLib = LoadLibrary("KERNEL32.DLL")
IF ISFALSE hLib THEN
   MSGBOX "KERNEL32.DLL cannot be found or loaded!"
ELSE
   ' We have a handle to the DLL!
END IF

2- If that succeeded, the next step is to query whether the name of the Function is present in the DLL. For this, we use the precise name given in the original ALIAS clause.

LOCAL pFunc AS DWORD
' Correct capitalization is essential
pFunc = GetProcAddress(hLib, "GetDiskFreeSpaceExA")
IF ISFALSE pFunc
   MSGBOX "KERNEL32.DLL does not contain ""GetDiskFreeSpaceExA""!"
ELSE
   ' We have the address of the target Sub/Function
END IF

3- At this point, assuming the Function is present...

LOCAL szPath AS ASCIIZ * %MAX_PATH, FreeBytesTo App&&
LOCAL TotalBytes&&, TotalFreeBytes&&, Result&
CALL DWORD pFunc USING tmp_GetDiskFreeSpaceEx("C:\", _
   FreeBytesToApp&&, TotalBytes&&, _
   TotalFreeBytes&&) TO Result&

4- That worked well, of course, but it sure was tedious! How about a better alternative in PowerBASIC? (You just knew that was coming, didn't you?) New in the latest versions (PB/CC 6.0 and PB/WIN 10.0) is the IMPORT ADDR statement. Do all the lookup in one line of code...

   IMPORT ADDR "GetDiskFreeSpaceExA", "Kernel32.DLL" TO p&

There you have it. If p& is non-zero, it contains the address of the target function. Otherwise, the function was not found. Now, just use p& to call the function with CALL DWORD p&... and you're ready to roll!

   A fairly spiffy new feature in the new PowerBASIC!


THE POWER Changes Everything

Just in case you're one of the few... who hasn't yet upgraded to the latest compilers -- Stay with me for a minute?

Now is the time to move. Full product purchases are just $199 and $169. Pretty refreshing compared to some of the $2,000-$5,000 prices from the competition! If you qualify for an upgrade, you can still take advantage of special pricing. Upgrade PB/WIN 9 to PowerBASIC 10.0 for just $99 -- upgrade PB/CC 5 to PB/CC 6.0 for just $89! There is no reason to wait... today is the day to upgrade.

Of course, PB/CC is our Console Compiler -- creates programs with a text mode user interface. Easy to use. Easy to port from DOS. It's the perfect solution for CGI Internet applications. Any time you want pure performance and nothing more! PowerBASIC 10 for Windows gives you the "look and feel" of a graphical user interface (GUI), the essence of Windows. Frankly, they've both taken a big leap forward.

Transparent Unicode

You know, a good compiler offers you ANSI strings. This has been the standard for many years. A better compiler lets you choose between ANSI and UNICODE in each program. But only one of them per program. If you want Unicode, you can't keep binary bytes in a string. It simply won't work. If you want ANSI, you can't have Unicode without exhaustive conversions. Not so good.

A great compiler, like PowerBASIC, supports all of them in the same program. And it's totally transparent. With PowerBASIC 10.0 for Windows (or PowerBASIC Console Compiler 6.0), you can have it all. One variable with ANSI. Another with UNICODE. Mix and match any way you choose with PowerStrings. All the messy details, and even the needed translations, are handled automatically by the compiler.

You can finally display a Euro symbol. Unicode text in a GUI or a Console. Read and write a Unicode file. Even print Unicode text on a Windows printer!

Static Link Libraries

Compile all your general purpose code into static units. Then, when it's needed, just $LINK it into your EXE or DLL and you're on your way. It's pre-compiled, so it's perfect for team programming. What will it do for third-party tools? Plenty. PerfectSync has already released SQL Tools 3. It links right into your EXE, so there's no need to drag a DLL around. Just $LINK and go. Lots more tools are sure to follow. And, if that's not enough, you'll get a librarian, too. Combine any number of units to a single library, and just use one single $LINK. PowerBASIC just discards those which aren't necessary. SLL's can contain Subs, Functions, and Object Classes. How easy can it get?

Automatic Dead Code Removal

Fight the war on BloatWare. Now, you can include big libraries of useful code -- PowerBASIC cleans it up for you. Any Sub/Function not used is automatically ignored when compiled. In fact, even Classes are pared down by similar Method and Property removal.

Order Now?     GOTO https://shop.powerbasic.com/

There's more. Lots, lots more. A completely new IDE based on Tabs, with syntax display as you type! Transparent Unicode. Print Preview. Thread Objects. A built in Resource Compiler. A StringBuilder Class. PowerArray class encapsulates SafeArray structures. A DEC$ function formats decimal numbers. Graphic Windows with scroll bars and scroll keys, user drag to resize, clip areas, and wrap by whole word. ENUM blocks, PREFIX blocks, ASMDATA blocks. THREADSAFE option for functions and methods. TEXT windows, Text Split, and the new FASTPROC procedures. There's more, but it's easy to see this is a very important upgrade.

SQL Tools version 3

You can use the power of SQL to access relational databases from Microsoft Access, SQL Server, Oracle, FoxPro, dBase, Btrieve, and 50 other popular formats. Open a database with a single line of code, and use standard SQL statements to build powerful, sophisticated, multi-user database programs! This is a total database solution.

This product has earned accolades from virtually all of its users. Version 3 is certainly no exception. With both a DLL and an SLL, you'll have the option to just $LINK units and libraries right into your EXE. No more DLL's to drag around, unless you choose it. Even better, PowerBASIC will only link the code that's necessary. Version 3 is faster and leaner, even with all the new features.

Many functions have been simplified. You can retrieve all rows in a single operation. You'll also get improved trace files, Quad integers, Unicode, plus enhanced Memo and BLOB field support. Then there's improved Microsoft Access database support, and much more! Documentation is provided in CHM, HLP, and PDF formats.

You can order right now...

PB/WIN 10.0 is priced at $199, while PB Console Compiler is $169. Upgrades from versions 9 and 5 are just $99 and $89 respectively. SQL Tools Pro is $199.95, while SQL Tools Std is $99.95. Upgrades from version 2 are $99.95 and $69.95 respectively.

Need more info?

We have a page created just for you. It's "Why should I upgrade?"

GOTO http://www.powerbasic.com/products/whyupcc.asp
GOTO http://www.powerbasic.com/products/whyupwin10.asp

Need even more info?

The complete documentation for both PB/CC 6 and PB/WIN 10 can be found right on the PowerBASIC Web Site! To see the 100% complete documentation:

          GOTO www.powerbasic.com -- Then [click] HELP DESK

You'll find everything you need to know to make an informed decision. You can order right now by replying to this email. You can call us today at (888)659-8000 or (941)473-7300, or fax us at (941)681-3100.

You can visit https://shop.powerbasic.com/ to place an e/order on our secure web site, or even mail an order to our offices. But no matter what method you choose, do it today and do it with confidence. Every product PowerBASIC ships for physical delivery is offered with a money-back guarantee for a full 30 days from the transaction date.


Regards,

Bob Zale, President
PowerBASIC Inc.


PowerBASIC Price List

PB/CC Console Compiler 6.0 - Full Product $169.00
PB/CC Console Compiler 6.0 - Upgrade from ver 5 $89.00
PB/CC Console Compiler 6.0 - Upgrade from prior versions $119.00
   Add Printed Documentation $49.00
PowerBASIC for Windows 10.0 (GUI) - Full Product $199.00
PowerBASIC for Windows 10.0 - Upgrade from ver 9 $99.00
PowerBASIC for Windows 10.0 - Upgrade from prior versions    $129.00
   Add Printed Documentation $49.00
Classic PowerBASIC 8 for Windows $99.00
Classic PowerBASIC for Console Compiler 4 $89.00
PowerBASIC for DOS 3.5 - Full Product $99.00
PowerBASIC for DOS 3.5 - Upgrade from prior versions $49.00
   Add Printed Documentation (2 book set) $29.00
PowerTree BTree Manager for DOS and Windows $99.00
PowerBASIC Forms Visual Designer ver 2.0 $99.00
SQL Tools Standard Version 3.0: $ 99.95
   Upgrade from ver 2 (Std) $69.95
SQL Tools Professional Version 3.0: $199.95
   Upgrade from ver 2 (Pro) $99.95
   Upgrade from ver 2 (Std) $129.95
Graphics Tools Standard ver 2 for PB/CC & PB/WIN $69.95
Graphics Tools Professional ver 2 for PB/CC & PB/WIN $139.95
Graphics Tools Standard ver 2 Upgrade from ver 1 $44.95
Graphics Tools Professional ver 2 Upgrade from ver 1 $114.95
Graphics Tools Professional ver 2 Upgrade from ver 2 Std $79.95
Console Tools Standard: $49.95
Console Tools Professional: $99.95


Shipping/Handling:

Any SoftwareSoftware
& 1 book
Each
Addl Book
Email/Download$6N/AN/A
UPS Ground/Mail US$10$10$ 8
Express 2-day US$18$18$14
Express 1-day US$28$35$30
Air Mail Canada/Mex    $10$18$18
Express Canada/Mex$30$40$34
Air Mail Intl$14$28$28
Express Intl$36$46$40


Order online at shop.powerbasic.com/ or just send an email with all pertinent information to: sales@powerbasic.com

We'll take it from there!

Most PowerBASIC products (those without printed books) can now be delivered by electronic mail. No wait for a package to arrive... No high shipping costs... For just $6 per order, no matter how many products, we'll deliver directly to your computer. If you're outside the U.S., savings might be greater. You won't pay taxes or duties to a freight company or postal service, because they aren't involved in the delivery. Check your tax code to be sure, but some countries charge no tax at all on transactions of this type. It could just be your lucky day!

Send your subscription request to email@powerbasic.com and please include your name and all email addresses you'd like to add, as well as your Zip or Postal Code. If you know someone else who would enjoy this newsletter please forward a copy to them so they can subscribe.

All contents Copyright (c) 2012 PowerBASIC Inc All Rights Reserved. PowerBASIC, PB/CC, PowerBASIC Forms, and PowerTREE are trademarks of PowerBASIC Inc. Other names are trademarks or registered trademarks of their respective owners.

PowerBASIC Gazette - Electronic Edition
Volume 1 - Issue 112
PowerBASIC, Inc. (888) 659-8000 Sales
2061 Englewood Road (941) 473-7300 Voice
Englewood, FL 34223     (941) 681-3100 Fax

Visit us on the Net at www.powerbasic.com    Email Sales at sales@powerbasic.com