I am attempting to access a 3rd party DLL.
' HIME.EBA
$MAIN
AUTODEFINE "OFF"
$USE "hime.lib"
DECLARE EXTERN hi_PutRegAsciiz (azData AS string, lReg AS INT),INT
DEF time1 AS INT
DEF time2 AS INT
def i as int
OPENCONSOLE
time1 = TIMER
time2 = TIMER
PRINT
i = hi_PutRegAsciiz( "hime.ini", 1 )
PRINT time2-time1, "secs."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end program."
PRINT
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
This is the original "DECLARE" as written in PowerBASIC.
DECLARE FUNCTION hi_PutRegAsciiz LIB "HIME.dll"( azData AS ASCIIZ , lReg AS LONG ) AS LONG
The original DLL has been converted to a lib.
Here is the result of my compile:
Compiling...
HIME.EBA
No Errors
Linking...
Emergence Linker v1.11 Copyright ÂÃ,© 2006 Ionic Wind Software
Unresolved external hi_PutRegAsciiz
Error: Unresolved extern hi_PutRegAsciiz
Error(s) in linking F:\Program Files\EBDev\projects\BOB\HIME\HIME\HIME.exe
Using "IMPORT," instead of "EXPORT" doesn't work either.
What am I doing wrong?
Depends on the language it came from. Try using an underscore in the name and declare.
DECLARE import, _hi_PutRegAsciiz (azData AS string, lReg AS INT),INT
...
i = _hi_PutRegAsciiz( "hime.ini", 1 )
Some languages don't create proper export records and the size of parameters is included in the exported name like:
DECLARE import, hi_PutRegAsciiz@8(azData AS string, lReg AS INT),INT
Which would be 4 bytes for the string address and 4 for the INT. C without a proper export definition file will use both the underscore and the parameter size on stdcall funcitons.
...then you must also find out whether the language in question is using stdcall or cdecl conventions. Which you'll know after you get it to link. If it crashes then it should be DECLARE CDECL import,...
Paul.
The language is P o w e r B A S I C.
The underscore thingy didn't work.
Compiling...
HIME.EBA
No Errors
Linking...
Emergence Linker v1.11 Copyright ÂÃ,© 2006 Ionic Wind Software
Unresolved external __imp__hi_PutRegAsciiz
Error: Unresolved extern __imp__hi_PutRegAsciiz
Error(s) in linking F:\Program Files\EBDev\projects\BOB\HIME\HIME\HIME.exe
Can't help then. Incompatible DLL.
Did you try the @8 at the end of the name like I suggested?
Also you need to know whether the foreign language pushes strings by value or by reference.
Paul.
Better yer, Download PE Browse Professional
http://www.smidgeonsoft.prohosting.com/software.html
Load the PB DLL and it will show you all the exported names.
@8 didn't work.
The symbols are apparently in uppercase.
What did PE Browse show for the export list of the DLL ? Try and match the name exactly, if you right click on the "Exports" tag on the left on PE Browse you can copy all of the exported names to the clipboard and paste in a text file. Use the name without the numbers in Parenthesis.
For example our 3D DLL shows this as the export list:
InitD3DWindowed (2) (0x0001239D)
dxReset (85) (0x000125C3)
dxSetFont (107) (0x00012647)
dxWriteText (141) (0x000126BC)
dxCleanup (15) (0x000126FC)
dxRender (84) (0x00012767)
....
Paste it here if you need to.
Paul.
The hime.dll exports functions with uppercase, so you should declare the imports like HI_PUTREGASCIIZ.
My dll2lib tool shows that it uses stdcall calling convention.
I now have a clean compile with uppercase names.
Unfortunately, The program abends when it enters the sub HI_PUTREGASCIIZ. I have contacted the author and we will see what he can do.
It may be that PB uses BYVAL strings instead of BYREF, which is the older MS BASIC way of doing things.
In that case you can force Emergence to send a string by value using a UDT.
TYPE BVSTRING
STRING s
ENDTYPE
declare import,HI_PUTREGASCIIZ(azData AS BVSTRING BYVAL, lReg AS INT),INT
BVSTRING bvs
bvs.s = "hime.ini"
HI_PUTREGASCIIZ(bvs, 1)
Paul.
Just for my info, this won't force it to pass byval:declare import,HI_PUTREGASCIIZ(azData AS STRING BYVAL, lReg AS INT),INT
without using the UDT?
Larry
Here are my results to date:
Note: I get the same results no matter which declare I use.
' HIME3.EBA
$MAIN
AUTODEFINE "OFF"
$USE "hime_iotest.lib"
'DECLARE IMPORT, HI_PUTREGASCIIZ (azData AS string, lReg AS INT),INT
declare import, HI_PUTREGASCIIZ(azData AS STRING BYVAL, lReg AS INT),INT
DEF azData AS string
DEF time1 AS INT
DEF time2 AS INT
def i as int
OPENCONSOLE
time1 = TIMER
time2 = TIMER
PRINT
azData = "hime.ini"
PRINT "I got to here."
i = HI_PUTREGASCIIZ( azData, 1 )
PRINT "But not to here."
PRINT time2-time1, "secs."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end."
PRINT
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
/*
OUTPUT:
I got to here.
-- hi_PutRegAsciiz
Ascii: hime.ini
Hex : 696E692E656D6968
String length: 8
*/In this version, neither declare works.
' HIME2.EBA
$MAIN
AUTODEFINE "OFF"
$USE "hime_iotest.lib"
TYPE BVSTRING
STRING s
ENDTYPE
declare import,HI_PUTREGASCIIZ(azData AS BVSTRING BYVAL, lReg AS INT),INT
'declare import,HI_PUTREGASCIIZ(azData AS BVSTRING, lReg AS INT),INT
BVSTRING bvs
DEF time1 AS INT
DEF time2 AS INT
def i as int
OPENCONSOLE
time1 = TIMER
time2 = TIMER
PRINT
bvs.s = "hime.ini"
PRINT "I got to here."
i = HI_PUTREGASCIIZ(bvs, 1)
PRINT "But not to here."
PRINT time2-time1, "secs."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end."
PRINT
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
/*
OUTPUT:
I got to here.
-- hi_PutRegAsciiz
Ascii: hime.ini
Hex : 696E692E656D6968
String length: 8
*/To answer your questions to date:
Quote from: Larry McCaughn on February 08, 2008, 01:02:06 PM
Just for my info, this won't force it to pass byval:declare import,HI_PUTREGASCIIZ(azData AS STRING BYVAL, lReg AS INT),INT
without using the UDT?
Larry
Yes, Larry, it does work.
Quote from: Paul Turley on February 08, 2008, 12:34:14 PM
It may be that PB uses BYVAL strings instead of BYREF, which is the older MS BASIC way of doing things.
In that case you can force Emergence to send a string by value using a UDT.
TYPE BVSTRING
STRING s
ENDTYPE
declare import,HI_PUTREGASCIIZ(azData AS BVSTRING BYVAL, lReg AS INT),INT
BVSTRING bvs
bvs.s = "hime.ini"
HI_PUTREGASCIIZ(bvs, 1)
Paul.
PB generally passes strings BYREF, but ASCIIZ strings can be sent BYVAL so long as its length is not greater than 64k. Neither method works.
Quote from: sapero on February 08, 2008, 04:44:38 AM
The hime.dll exports functions with uppercase, so you should declare the imports like HI_PUTREGASCIIZ.
My dll2lib tool shows that it uses stdcall calling convention.
Very nice dll2lib tool, Sapero.
The web page (http://www.devotechs.com/HIMEMain.html#What_is_HIME) for HIME shows that:
QuoteHIME is a 32 bits dll, so every programming language that can access a standard Win32 dll can use HIME: C, C++, C#, Visual Basic 5/6, VB.Net, Delphi, PowerBASIC, PureBASIC, Liberty Basic, Euphoria, Java, Macromedia Director (with GLU32)...
.NET (dot NET) languages can use HIME as an 'unmanaged code dll'.
HIME comes with demo and test programs (including their source code) to show HIMEs performance and as an example of how to use HIME.
Demo code in Visual Basic 5/6, C++, C#, VB.Net, Liberty Basic, Delphi, PowerBASIC and PureBASIC are also included.
HIME was written in PowerBASIC (*) and inline assembler.
HIME is designed to support all Windows operating systems.
(tested on Windows 98, XP and Vista)
QuoteQuote from: Paul Turley on February 08, 2008, 12:56:33 AM
What did PE Browse show for the export list of the DLL ? Try and match the name exactly, if you right click on the "Exports" tag on the left on PE Browse you can copy all of the exported names to the clipboard and paste in a text file. Use the name without the numbers in Parenthesis.
For example our 3D DLL shows this as the export list:
InitD3DWindowed (2) (0x0001239D)
dxReset (85) (0x000125C3)
dxSetFont (107) (0x00012647)
dxWriteText (141) (0x000126BC)
dxCleanup (15) (0x000126FC)
dxRender (84) (0x00012767)
....
Paste it here if you need to.
Paul.
Paul, PE Browse is a very nice tool. It shows the method names as you mentioned, but when I tried it with HIME.DLL, it showed only numbers.
Quote from: Paul Turley on February 07, 2008, 06:43:30 PM
Did you try the @8 at the end of the name like I suggested?
Also you need to know whether the foreign language pushes strings by value or by reference.
Paul.
PB passes strings BYREF.
The @8 produced the following messages:
QuoteCompiling...
HIME3.EBA
File: F:\Program Files\EBDev\projects\BOB\HIME\HIME\HIME3.EBA (20) Warning: undeclared function 'HI_PUTREGASCIIZ'
F:\Program Files\EBDev\projects\BOB\HIME\HIME\HIME3.EBA:20: error: symbol `HI_PUTREGASCIIZ' undefined
F:\Program Files\EBDev\projects\BOB\HIME\HIME\HIME3.EBA:28: error: phase error detected at end of assembly.
Error(s) in assembling "F:\Program Files\EBDev\projects\BOB\HIME\HIME\HIME3.a"
Quote from: Paul Turley on February 07, 2008, 05:19:16 PM
...then you must also find out whether the language in question is using stdcall or cdecl conventions. Which you'll know after you get it to link. If it crashes then it should be DECLARE CDECL import,...
Paul.
The PB is compiled with stdcall.
Thank you all for your help.
If you would like to try your hand, you can download the Demo containing the dlls from here (http://www.devotechs.com/downloads/HIME.zip).
To clarify a question above...
The BYVAL keyword is ignored for string types in Emergence, always has been as strings are passed by reference in 98% of the language out there. Including C and C++. And that is the way the Windows API expects them to be passed as well.
UDT's can be passed BYVAL which was a change a number of revisions back. So having a string as the only member of a UDT forces the string to be passed BYVAL.
Quote
In this version, neither declare works.
Care to clarify? Doesn't compile or doesn't work. If it is the former then what was the error message?
Quote
If you would like to try your hand, you can download the Demo containing the dlls from here.
No time for it myself. But I am sure someone else will take you up on it.
Paul.
Not to be a party pooper but...
$MAIN
AUTODEFINE "OFF"
$USE "hime_iotest.lib"
TYPE BVSTRING
STRING s
ENDTYPE
declare import,HI_PUTREGASCIIZ(azData AS BVSTRING)
BVSTRING bvs
DEF time1 AS INT
DEF time2 AS INT
def i as int
OPENCONSOLE
time1 = TIMER
time2 = TIMER
PRINT
bvs.s = "hime.ini"
PRINT "I got to here."
HI_PUTREGASCIIZ(bvs)
PRINT "But not to here."
PRINT time2-time1, "secs."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end."
PRINT
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
Works...
Your signature is all wrong in its definition.
Did you remember the age old simple thing such as TOOLS -> CREATE IMPORT LIBRARY -> *****ALL OF THE DLLS THAT CAME WITH HIME****
Then look at the signature of the method you are trying to use?
Not just the hime.dll, there are 4 total dll's in the kit.
OUTPUT
I got to here.
-- hi_PutRegAsciiz
Ascii: hime.ini
Hex : 696E692E656D6968
String length: 8
Register Number: 1207959552
--------------------------------------
But not to here.
0 secs.
Done...
Press any key to end.
Hi Jonathan,
I did remember to make the libs. But you are right about the signature. I forgot the register number. The author gave me some good ideas for implementation.
I want to thank everyone for their help.
I am going to start a new thread and show examples of the function calls as a sort of tutorial.