March 29, 2024, 02:16:28 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Declare DLL path

Started by Ziad Diab Electronics, May 11, 2017, 11:53:11 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Ziad Diab Electronics

Hello,

I am trying to declare a dll that's not in the System folder:

DECLARE "C:\Users\Public\Documents\calc.dll", GetLocalTime(tm:SYSTEMTIME)

It doesn't say in the user guide, is there an updated user guide ?

Thank for the help
Ziad Diab Electronics
Ziad Diab Electronics
ZDE

billhsln

Found this in my notes, maybe it will help.

QuoteRun the EB GUI and from menu select Tools->Create import library. Find
crtdll.dll and click ok, then answer YES for "replace existing
library" prompt.

Return to LIBS folder and rename the new crtdll.lib to _crtdll.lib,
then restore the original crtdll.lib.

Now append a $use "_crtdll.lib" so it should compile now.

I think that following this might get you to where you need.

Bill
When all else fails, get a bigger hammer.

LarryMc

Calling external DLL functions.

Creative BASIC has the ability to call an external DLL to further expand the capabilities of your program. DLL stands for Dynamic Link Library and can contain hundreds of functions for your use. Many DLL’s are included with the Windowsâ,,¢ operating system and more are available on the Internet.

To use a DLL you first need to define it to Creative BASIC using the DECLARE statement. DECLARE was discussed in an earlier chapter. The syntax of DECLARE when using a DLL is:

DECLARE "[!]DLL name", function({parameter list}) {, return type}
DECLARE "[!]DLL name", localname ALIAS function({parameter list}) {,return type}

If the DLL is in the windows system directory then a path is not required. For DLL's elsewhere you should use a fully qualified path name.  Once the DLL is declared you can use it in your program by simply treating it as any other function or statement. The second form of the syntax allows using a different name for the function to avoid naming conflicts with other DLL's or to declare the same function with different parameters.

The optional ! symbol specifies that the DLL function uses the CDECL calling convention. For most of the Windows API this is unnecessary with the exception of a few functions. wsprintfA is one of the functions that requires the cdecl calling convention.

Example declaration:

DECLARE "User32",MessageBoxA (wnd:window,text:string,title:string,flags:int),int

Declares a function called MessageBoxA in the DLL "User32" which is located in the system directory. The function takes a window, two strings and an integer as parameters and returns an integer result.

Example usage:

Result = MessageBoxA( w,"This is a message","Press OK",0 )

Documentation for Windowsâ,,¢ DLL’s can be found in any good programmers reference. Commercially available DLL’s include documentation that outlines all of the functions available.  In the documentation, you may see some variable types that do not match

any of  Creative BASIC’s  built-in types. The following table lists some common substitutes.

Requested type
Equivalent Creative BASIC type

HWND
WINDOW, DIALOG or INT

LPCSTR/LPSTR
STRING, ISTRING

BYTE / UBYTE / TCHAR
CHAR

LONG
INT

WORD
WORD

DWORD
INT

UINT
INT

BOOL
INT

WPARAM
INT

LPARAM
INT

LP* POINTER

Passing user types

Many DLL functions will require passing a structure, or user type, to the function. Creative BASIC's TYPE statement can be used to create the needed structure to be passed or modified by a function. An example of this is the GetLocalTime function located in kernel32.dll.   The function expects a variable of type SYSTEMTIME.   The type can be specified as follows:

TYPE SYSTEMTIME
    DEF wYear:WORD
    DEF wMonth:WORD
    DEF wDayOfWeek:WORD
    DEF wDay:WORD
    DEF wHour:WORD
    DEF wMinute:WORD
    DEF wSecond:WORD
    DEF wMilliseconds:WORD
ENDTYPE

Once the type is defined you can create a variable that can be used with the function

Example:

DECLARE "kernel32",GetLocalTime(tm:SYSTEMTIME)
DEF tm:SYSTEMTIME

GetLocalTime(tm)

PRINT tm.wYear

...

The DLL function may also require a certain packing to be used when passing the user type. Packing represents how a structure is stored in memory and can be specified in the TYPE statement as an optional parameter.

Example:

TYPE MYTYPE,2
    DEF letter:CHAR
    DEF num:INT
    DEF small:WORD
ENDTYPE

Would convert the type to a structure with 2 byte packing when passed to the DLL function.  If a packing number is not supplied you can generally omit the number in which case Creative BASIC defaults to a pack value of 8. Note that the packing number has no effect on user types used within your program and only effects DLL calls.

The POINTER type

Certain DLL functions might require a parameter of a pointer.  This allows the DLL function to modify the contents of a variable that was declared in Creative BASIC. Normally this is done with numeric variable types. An example of this would be the GetComputerName function located in kernel32.dll. The GetComputerName function expects a string variable and an integer variable which can be modified by the function. A pointer variable can 'point' to any of the built in variable types and then be passed to a function

Example:

DEF pSize:POINTER
DEF nSize:INT
DEF name:STRING
DECLARE "kernel32",GetComputerNameA(buffer:STRING,size:POINTER),int

nSize = 255
pSize = nSize

GetComputerNameA(name,pSize)
PRINT name
PRINT nSize
...

On return the function will have stored the computers name in 'name' and the number of characters in the name in 'nSize'. The function could have also been called with nSize directly and is internally converted to a pointer when the function is called. This happens since the function was declared as requiring type POINTER. We did not have to define a pointer for the string variable as all strings are passed by reference in Creative BASIC which allows the function to modify the contents of the string.

See the sample programs structuredemo.cba and pointerdemo.cba for more examples of using pointers and user types with DLL functions.

Passing Arrays
Arrays can be passed to DLL's by declaring the parameter with brackets []. Example:

DECLARE "mydll",SomeFunction(numbers[]:INT),INT
DEF data[10]:INT
...
SomeFunction(data)

Arrays are passed by reference and can be directly modified by the DLL.

Unloading a DLL
If your program is only going to use a DLL for a short time you can unload the DLL from memory with the FREELIB statement. Once a DLL is unloaded a call to a previously declared function will load the DLL again. The syntax of FREELIB is:

FREELIB name

It is not necessary to unload DLL's that are part of the system such as kernel32.dll or user32.dll since those libraries are always loaded when Windows start. A good example of when to use FREELIB would be a setup program that uses a DLL to create icons and then unloads it when finished. Another use would be a temporary DLL that you extract from resources. The DLL cannot be deleted until all references to it are freed.

All DLLs your program uses are unloaded when your program ends.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library