Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

API Calls from PowerBuilder.

657 views
Skip to first unread message

Luiz Paes

unread,
Oct 10, 1998, 3:00:00 AM10/10/98
to
Hi all,

I have a problem with API calls. I'd like to now how to call api
functions in a DLL that have some functions with parameters like this:

DLL:
function x ( stru_a )

Structure stru_a {
char * name,
integer * value_1,
Double * value_2,
.... }

I hope somebody can help me.
Thank's.
Luiz Paes.


psfr...@my-dejanews.com

unread,
Oct 14, 1998, 3:00:00 AM10/14/98
to
In article <361F987B...@uol.com.br>,

This is one from sysbase tech docs. May be this will help u.


Prototyping API Calls for PowerBuilder 4.0, 5.0, and 6.0

he tens of thousands of function calls in the Windows environment can be
helpful to PowerBuilder users, but documenting them is nearly impossible.
After hundreds of user inquiries, Powersoft Technical Support compiled these
technical tips as FaxLine document 44648 to enable PowerBuilder developers to
translate standard Microsoft function calls into PowerBuilder syntax, and to
empower developers to use any of the external API calls within their
PowerBuilder environments. In this issue of Powerline, we've dedicated the
entire space of our "Techical News" section to provide you with this
important information. The FaxLine document has been annotated here so that
each step in the process will be clear for PowerBuilder developers with
varying degrees of experience. The following information will help you
translate any Windows SDK call to a PowerBuilder API function call. It
doesn't matter whether you're using PowerBuilder 4.0, 5.0, or 6.0 but there
are important differences between the 16- and 32-bit versions, as we'll
discuss below. Step 1: Converting an SDK Call to a PowerBuilder API Call.
First you need to get the syntax that will be converted. This can be obtained
from either a Windows API Bible or the MSDN (Microsoft Developers Network).
Step 2: Determining Whether it is a Function or a Subroutine. Function calls
return a value; subroutines do not. Here is an example of a Microsoft
function: BOOL GetFileVersionInfo( LPTSTR lptstrFilename, DWORD dwHandle,
DWORD dwLen, LPVOID lpData ); Here is an example of a Microsoft subroutine:
VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) Step 3: Converting the Data
Types from Microsoft to PowerBuilder. Most of the data types are listed
above, but some may be missing. When in doubt, it's usually safe to assume
that 16-bit data types are "unit" and 32-bit are "ulong", since they are the
most common. *If the word "Callback" appears as a data type, it cannot be
performed within PowerBuilder. Callback routines are functions that are
called from within functions. Step 4: Declaring a Local or Global External
Function. This is a Microsoft function: BOOL GetFileVersionInfo( LPTSTR
lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData ); The BOOL
represents a boolean return code, which is translated to "Boolean" in
PowerBuilder for both 16 and 32 bit. A LPTSTR means a pointer to a string
(see Step 3). In PowerBuilder, simply use the word "ref" before declaring the
string for either 16- or 32-bit platforms. DWORD is translated to "uint" for
16 bit and "ulong" for 32 bit. An LPVOID indicates that a structure is being
used. In PowerBuilder, create a structure, assign it to an instance variable
of that structure, and pass it by reference. As a result, the following
function declarations can be derived: PowerBuilder 16 bit: FUNCTION boolean
GetFileVersionInfo(ref string filename, uint f_handle, uint f_length, ref
lpdata lpdata2) LIBRARY "ver.dll" PowerBuilder 32 bit: FUNCTION boolean
GetFileVersionInfoA(ref string filename, ulong f_handle, ulong f_length, ref
lpdata lpdata2) LIBRARY "version.dll" Note: In the "gotchas" section below,
you'll get a further explanation why an "A" is appended to the 32-bit
function. You'll also find a handy technique to help you locate function
calls within the DLLs. Step 5: Creating a Structure. A structure, a container
for one or more elements, is the mechanism used by the operating system to
pass required information back from a function. The MSDN provides all
information on this structure since it is a Windows function. In the MSDN,
the structure appears like this: LPDATA = { DWORD dwSignature ; DWORD
dwStrucVersion ; DWORD

dwFileVersionMS ; DWORD dwFileVersionLS ; DWORD dwProductVersionMS ;

DWORD dwProductVersionLS ; DWORD dwFileFlagsMask ; DWORD dwFileFlags ;

DWORD dwFileOS ; DWORD dwFileType ; DWORD dwFileSubtype ;


DWORD dwFileDateMS ; DWORD dwFileDateLS } In PowerBuilder, go into the
Structure Painter, as shown in the above example, to convert all the elements
to PowerBuilder data types. By looking at Step 3, DWORD translates to
"ulong". Step 6: Scripting the Function Call. Now that you have the function
declaration, you'll need to assign it the proper arguments. The function
GetFileVersionInfoA listed in Step 4 requires the script below. First you'll
need to declare the data types. Keep in mind that the variable names do not
have to match the function declaration listed in Step 4.

boolean lb_rtn // Return code string ls_filename //
1st argument - filename ulong lu_hand // 2nd argument - f_handle
ulong lu_len // 3rd argument - f_length lpdata
lpdata2 // Last argument - assigning an instance of a structure. Step 7:
Assigning Values to the Arguments. This is the hardest part; it may require
use of the MSDN, API Bible, or available references that cover the function
you are calling. In this particular case, the information is contained within
the MSDN. The first argument, ls_filename, should be set to the path and
filename of the target file. ls_filename = "c:\windows\calc.exe" //
The calculator would be a good file to test against. The second argument,
lu_hand according to the MSDN, is ignored. This is probably reserved for a
future version of Windows to use. To be safe, set the argument to null.
setnull(lu_hand) The third argument lu_len, contains the size of the buffer
into which the information will be returned. It is critical that the buffer
size not be too small because the information could overflow into another
part of memory, causing a GPF or Dr. Watson error. In this particular case,
since the structure contains 13 elements that are all "ulong", the number 256
should be sufficient to contain the information. lu_len = 256 The last
argument, lpdata2, is an instance of the structure lpdata and will be
populated by the function call. The final script will appear as follows:
boolean lb_rtn long ls_filename ulong lu_hand, lu_len lpdata
lpdata2 ls_filename = "c:\windows\calc.exe" // The calculator would be a
good file to test against. setnull(lu_hand) lu_len = 256
lb_rtn = GetFileVersionInfoA(ls_filename, lu_hand, lu_len, lpdata2) Step 8:
Viewing the Output. sle_1.text = string(lpdata2.dwSignature)
sle_2.text = string(lpdata2.dwStrucVersion) sle_3.text =
string(lpdata2.dwFileVersionMS) sle_4.text =
string(lpdata2.dwFileVersionLS) sle_5.text =
string(lpdata2.dwProductVersionMS) sle_6.text =
string(lpdata2.dwProductVersionLS) sle_7.text =
string(lpdata2.dwFileFlagsMask) sle_8.text = string(lpdata2.dwFileFlags)
sle_9.text = string(lpdata2.dwFileOS) sle_10.text =
string(lpdata2.dwFileType) sle_11.text = string(lpdata2.dwFileSubtype)
sle_12.text = string(lpdata2.dwFileDateMS) sle_13.text =
string(lpdata2.dwFileDateLS) Messagebox("Return Code", string(lb_rtn))
Additional Information: Gotchas to Look Out For. 1. Make sure the DLL you are
referencing is the right bit level. To ensure the referenced DLL is at the
proper bit level, view the DLLs' properties. Most likely, however, you'll
need a third-party product to determine this. I'd recommend Function Check
from Karri Software LTD (http://ourworld.compuserve.com/homepages/KarriSL/)
or QuickView, an accessory of Win95 PLUS! from Microsoft. Remember, a 16-bit
application cannot make a 32-bit API call and vice versa. 2. Some functions
are cap sensitive depending on the DLL. For example, Findwindowa fails,
whereas FindWindowA works. 3. All handles in PowerBuilder 16 bit are "uint"
and 32 bit are "ulong". Using the data types "int" or "long" may work, but if
the handle points to an area in high memory, the latter two data types may
not be able to support such a large number. This is more likely to happen on
NT 4.0. 4. Make sure you have the correct function name. Under 32 bit, many
of the functions had an "A" appended to the function name to make it unique
from its 16-bit counterpart. This allows developers to place both 16-bit and
32-bit function calls in the same application and then make the correct
function call based on what bit platform the program is being run from.
Again, you'll need to use a third-party product to verify this. The MSDN does
not always list the proper names for the functions. For example,
GetFileVersionInfo is listed as a 32-bit function, but it is in fact
GetFileVersionInfoA. 5. Global versus Local External Function declaration: If
the function is declared globally, it can be called from anywhere in your
application. If you declare the function as a Local External Function, it can
only be called from that window where it's declared. Local Function uses less
resources than globals, but the difference is minimal. Error Messages and
What They Mean. 1. Error: Error opening DLL library <filename> for external
function at line <line_number> in the <event name> event of object
<object_name> of <window_name>. This error message occurs if you try calling
a DLL that is not the same bit level as your application. This could also
mean that the DLL is corrupted, in an incompatible format, or the DLL can't
be found. As a result, PowerBuilder is trying to load the DLL into memory but
is unable to. In most cases, this error message is not a PowerBuilder
problem. 2. Error: Error calling external function <function_name> at line
<line_number> in the <event name> event of object <object_name> of
<window_name>. This is probably the result of an incorrectly spelled function
name. Be sure to verify that the function name matches what is in the DLL
exactly, including the case of the letters. 3. Error: Specified argument type
differs from required argument type at runtime in DLL function
<function_name>. (Invalid stack pointer on return from function call) at line
<line_number> in <event_name> event of object <object_name> of <window_name>.
This error usually indicates that the data types do not match what the DLL
function is expecting. 4. PB050: Caused an Invalid Page Fault in module
PBSHR050.DLL @ 0137:1111163e This error can occur either immediately upon
calling the function or when the application closes. The module and memory
address may vary, but the reason for this is usually the same. If
PowerBuilder is receiving a string and memory isn't allocated in advance
using the SPACE( ), that string will overflow into another memory area. To
allocate 12 characters to the string ls_filename, the following code would be
used: ls_filename = space(13) // You may want to give it an extra space just
to be safe. 5. Receiving garbage from the DLL. E.g., last name populated as:
^&Ryan This problem is most likely the result of the byte alignment being set
incorrectly. PowerBuilder expects the byte alignment to be set to one, and if
you are using MSVC++ compiler, the default setting is four. To set the byte
alignment to one, you'll need to do the following prior to compiling to a
DLL: · Select the desired target. · Right mouse click and select Settings. ·
Select the C/C++ tabpage. · Select Code Generation from the Category dropdown
list. · Select desired byte alignment from the Struct Member Alignment
dropdown list. Note: This is only relevant when working with structures. A
Handy Trick for Finding Functions Quickly. 1. On Win95 or NT 4.0, click on
the START button and select "Find", then "Files or Folders". 2. In the SLE
entitled "Named" enter c:\*.dll. If this is a Windows DLL that you'll be
calling, enter c:\windows\*.dll. 3. Click on the "Advanced" tab and in the
"Containing Text" SLE, enter the exact function name you are looking for. For
example: FindWindowA 4. There will usually be a lot of DLLs that contain the
function you are looking for but try to use the main Windows DLLs whenever
possible since they are already loaded into memory. Related FaxLine
Documents. 44596 - 16-Bit API Calls for PowerBuilder 4.0, 5.0, and 6.0 44545
- 32-Bit API Calls for PowerBuilder 4.0, 5.0, and 6.0 44588 - Dynamically
Closing a Non-PowerBuilder Application 44474 - External Function Calls (PB
4.0, 5.0) 44538 - Passing a 32-bit PowerBuilder structure to a 32-bit C DLL
Created in Power++ PowerBuilder API Call Web site:
http://www.ultranet.com/~dsalomon/api


Copyright © 1998 Sybase, Inc. All Rights Reserved.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum

Zane Knight

unread,
Oct 15, 1998, 3:00:00 AM10/15/98
to
Search the Help file for Declaring External Functions and then Calling
External Functions. This will explain how (and where) to declare and call
your API functions.

Zane Knight.

0 new messages