Page 1 of 2
Error with CallFunction...
Posted: Tue Sep 01, 2009 7:43 pm
by DevilDog
Hey everyone,
I'm getting an error:
Bad paremeter type, number expected instead of a string
on this line of code:
Code: Select all
dwLen = CallFunction(1,"GetFileVersionInfoSizeA",lptstrFilename$,@lpdwHandle)
Problem is that I haven't changed that code at all. The only thing that has changed is that I upgraded to the lastest 4.40 Beta version 2. Also, the parameter types seem to match the function's tooltip help definition.
Anyone know what I might be able to check?
Thanks
Devildog
Posted: Tue Sep 01, 2009 7:48 pm
by srod
Code: Select all
dwLen = CallFunction(1,"GetFileVersionInfoSizeA",@lptstrFilename$,@lpdwHandle)
Posted: Tue Sep 01, 2009 7:54 pm
by DevilDog
Srod,
Thanks for the help, now I'm getting
Bad parameter type: a string is expected
Any ideas?
Devildog
Posted: Tue Sep 01, 2009 7:58 pm
by srod
My first post was incorrect and I since edited the post. Please check that you are using the following :
Code: Select all
dwLen = CallFunction(1,"GetFileVersionInfoSizeA",@lptstrFilename$,@lpdwHandle)
Posted: Tue Sep 01, 2009 8:00 pm
by DevilDog
I tried that as well and I'm receiving the same thing:
Bad paremeter type, number expected instead of a string
Posted: Tue Sep 01, 2009 8:01 pm
by srod
Doesn't make sense.
Can you post the code?
Posted: Tue Sep 01, 2009 8:03 pm
by DevilDog
Sure, this is the whole procedure:
Code: Select all
Procedure.s GFVI_GetInfo(lptstrFilename$,lekFlags,bFieldName);- get exe/dll file information [gfvi]
;CallDebugger
Protected lpdwHandle.l, dwLen.w, lpData.l, lplpBuffer.l, puLen.l, *pBlock, lpSubBlock$
Protected nSize.w, szLang$, bBit.b, lekFlag.l, sElement$, sGFVI$
lplpBuffer = 0 : puLen = 0 : sGFVI$ = "" : nSize = 128 : szLang$ = Space(nSize)
If FileSize(lptstrFilename$)>0
If OpenLibrary(1,"Version.dll")
dwLen = CallFunction(1,"GetFileVersionInfoSizeA",@lptstrFilename$,@lpdwHandle)
If dwLen>0
*pBlock=AllocateMemory(dwLen)
If *pBlock>0
Result = CallFunction(1,"GetFileVersionInfoA",lptstrFilename$,0,dwLen,*pBlock)
If Result
lpSubBlock$ = "\\VarFileInfo\\Translation"
Result = CallFunction(1,"VerQueryValueA",*pBlock,lpSubBlock$,@lplpBuffer,@puLen)
If Result
CPLI$ = RSet(Hex(PeekW(lplpBuffer)),4,"0")+RSet(Hex(PeekW(lplpBuffer+2)),4,"0")
Result = CallFunction(1,"VerLanguageNameA",PeekW(lplpBuffer),@szLang$,nSize)
EndIf
lekFlag = 1
For bBit = 1 To 12
If lekFlag & lekFlags
sElement$ = GFVI_GetElementName(lekFlag)
lpSubBlock$ = "\\StringFileInfo\\"+CPLI$+"\\"+sElement$
Result = CallFunction(1,"VerQueryValueA",*pBlock,lpSubBlock$,@lplpBuffer,@puLen)
If Result
If sGFVI$<>"" : sGFVI$+Chr(10) : EndIf
If bFieldName
sGFVI$=sGFVI$+sElement$+":"+Chr(9)+PeekS(lplpBuffer)
Else
sGFVI$=sGFVI$+PeekS(lplpBuffer)
EndIf
EndIf
EndIf
lekFlag << 1
Next
If lekFlag & lekFlags
If sGFVI$<>"" : sGFVI$+Chr(10) : EndIf
If bFieldName
sElement$ = GFVI_GetElementName(lekFlag)
sGFVI$ = sGFVI$+sElement$+":"+Chr(9)+szLang$
Else
sGFVI$ = sGFVI$+szLang$
EndIf
EndIf
EndIf
FreeMemory(*pBlock)
EndIf
EndIf
CloseLibrary(1)
EndIf
EndIf
ProcedureReturn sGFVI$
EndProcedure
Posted: Tue Sep 01, 2009 8:04 pm
by srod
REMOVED.
Posted: Tue Sep 01, 2009 8:06 pm
by DevilDog
well like I said, it was working up until the beta. I'm going to revert back to the release version and see if that fixes it.
Posted: Tue Sep 01, 2009 8:09 pm
by DevilDog
Yeah, must be a bug because it works under 4.31. Where can I post this to alert the PB team?
Posted: Tue Sep 01, 2009 8:09 pm
by srod
I take back the confirmed part. The following runs fine.
Code: Select all
If OpenLibrary(0, "User32.dll")
CallFunction(0, "MessageBoxA", 0, @"hi", @"hello", 0)
CloseLibrary(0)
EndIf
Posted: Tue Sep 01, 2009 8:11 pm
by srod
Hang on, you haven't adjusted all of your CallFunction()'s correctly!
Try the following :
Code: Select all
Procedure.s GFVI_GetInfo(lptstrFilename$,lekFlags,bFieldName);- get exe/dll file information [gfvi]
;CallDebugger
Protected lpdwHandle.l, dwLen.w, lpData.l, lplpBuffer.l, puLen.l, *pBlock, lpSubBlock$
Protected nSize.w, szLang$, bBit.b, lekFlag.l, sElement$, sGFVI$
lplpBuffer = 0 : puLen = 0 : sGFVI$ = "" : nSize = 128 : szLang$ = Space(nSize)
If FileSize(lptstrFilename$)>0
If OpenLibrary(1,"Version.dll")
dwLen = CallFunction(1,"GetFileVersionInfoSizeA",@lptstrFilename$,@lpdwHandle)
If dwLen>0
*pBlock=AllocateMemory(dwLen)
If *pBlock>0
Result = CallFunction(1,"GetFileVersionInfoA",@lptstrFilename$,0,dwLen,*pBlock)
If Result
lpSubBlock$ = "\\VarFileInfo\\Translation"
Result = CallFunction(1,"VerQueryValueA",*pBlock,@lpSubBlock$,@lplpBuffer,@puLen)
If Result
CPLI$ = RSet(Hex(PeekW(lplpBuffer)),4,"0")+RSet(Hex(PeekW(lplpBuffer+2)),4,"0")
Result = CallFunction(1,"VerLanguageNameA",PeekW(lplpBuffer),@szLang$,nSize)
EndIf
lekFlag = 1
For bBit = 1 To 12
If lekFlag & lekFlags
sElement$ = GFVI_GetElementName(lekFlag)
lpSubBlock$ = "\\StringFileInfo\\"+CPLI$+"\\"+sElement$
Result = CallFunction(1,"VerQueryValueA",*pBlock,@lpSubBlock$,@lplpBuffer,@puLen)
If Result
If sGFVI$<>"" : sGFVI$+Chr(10) : EndIf
If bFieldName
sGFVI$=sGFVI$+sElement$+":"+Chr(9)+PeekS(lplpBuffer)
Else
sGFVI$=sGFVI$+PeekS(lplpBuffer)
EndIf
EndIf
EndIf
lekFlag << 1
Next
If lekFlag & lekFlags
If sGFVI$<>"" : sGFVI$+Chr(10) : EndIf
If bFieldName
sElement$ = GFVI_GetElementName(lekFlag)
sGFVI$ = sGFVI$+sElement$+":"+Chr(9)+szLang$
Else
sGFVI$ = sGFVI$+szLang$
EndIf
EndIf
EndIf
FreeMemory(*pBlock)
EndIf
EndIf
CloseLibrary(1)
EndIf
EndIf
ProcedureReturn sGFVI$
EndProcedure
Posted: Tue Sep 01, 2009 8:20 pm
by DevilDog
OK, the code you posted compiles fine under 4.40 beta 2 with the changes you made.
What's changed? why did the old code work under 4.31 and not under the beta?
Posted: Tue Sep 01, 2009 8:24 pm
by srod
When using a literal string such as "test", the compiler will now treat this as a string and will not automatically substitute the address of the underlying character array in situations in which the function prototype specifies an integer etc. Hence for api functions you need to use the "address of" operator @ etc.
By the way, since you are calling the same function(s) more than once you would be far better using CallFunctionFast(). Better still use prototypes. Even better, import the functions directly from the import library "Version.lib".
Posted: Tue Sep 01, 2009 8:52 pm
by DevilDog
Thanks for the explanation, it's great info.
And I'll look into your suggestions as well.