Import x86 only polink error

Just starting out? Need help? Post your questions and find answers here.
Rinzwind
Enthusiast
Enthusiast
Posts: 636
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Import x86 only polink error

Post by Rinzwind »

Code: Select all


Enumeration COMPUTER_NAME_FORMAT
  #ComputerNameNetBIOS
  #ComputerNameDnsHostname
  #ComputerNameDnsDomain
  #ComputerNameDnsFullyQualified
  #ComputerNamePhysicalNetBIOS
  #ComputerNamePhysicalDnsHostname
  #ComputerNamePhysicalDnsDomain
  #ComputerNamePhysicalDnsFullyQualified
  #ComputerNameMax  
EndEnumeration

Import "Kernel32.lib"
  GetComputerNameEx(NameType, lpBuffer.s, nSize) As "GetComputerNameExW"
EndImport
; Prototype GetComputerNameEx(NameType, r.s, size)
; OpenLibrary(1, "Kernel32.dll")
; Global GetComputerNameEx.GetComputerNameEx = GetFunction(1, "GetComputerNameExW")
; CloseLibrary(#PB_All)
Procedure.s GetComputerName(NameType = #ComputerNamePhysicalDnsFullyQualified)
  Protected r.s, size = 512
  r = Space(size)
  If GetComputerNameEx(NameType, r, @size)  
    ProcedureReturn Trim(r)
  EndIf  
EndProcedure

Debug GetComputerName()

; ---------------------------
; PureBasic - Linker error
; ---------------------------
; POLINK: error: Unresolved external symbol 'GetComputerNameExW'.
; 
; POLINK: fatal error: 1 unresolved external(s).
; 
; 
; ---------------------------
; OK   
; ---------------------------
It works fine in the 64-bit version, even without replacing the lib file with updated one. In 32 bit version, I can't get the import working even when replacing the x86 lib file with newer version from VS. The GetFunction variation works in 32 + 64 bit(second question, why that one still works even when CloseLibrary is called before calling the function?)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Import x86 only polink error

Post by wilbert »

Solution one (x86 only)

Code: Select all

Enumeration COMPUTER_NAME_FORMAT
  #ComputerNameNetBIOS
  #ComputerNameDnsHostname
  #ComputerNameDnsDomain
  #ComputerNameDnsFullyQualified
  #ComputerNamePhysicalNetBIOS
  #ComputerNamePhysicalDnsHostname
  #ComputerNamePhysicalDnsDomain
  #ComputerNamePhysicalDnsFullyQualified
  #ComputerNameMax 
EndEnumeration

Import "Kernel32.lib"
  GetComputerNameEx(NameType, lpBuffer.s, nSize) As "_GetComputerNameExW@12"
EndImport

Procedure.s GetComputerName(NameType = #ComputerNamePhysicalDnsFullyQualified)
  Protected r.s, size = 512
  r = Space(size)
  If GetComputerNameEx(NameType, r, @size) 
    ProcedureReturn Trim(r)
  EndIf 
EndProcedure

Debug GetComputerName()
Solution two (both x86 and x64)

Code: Select all

Enumeration COMPUTER_NAME_FORMAT
  #ComputerNameNetBIOS
  #ComputerNameDnsHostname
  #ComputerNameDnsDomain
  #ComputerNameDnsFullyQualified
  #ComputerNamePhysicalNetBIOS
  #ComputerNamePhysicalDnsHostname
  #ComputerNamePhysicalDnsDomain
  #ComputerNamePhysicalDnsFullyQualified
  #ComputerNameMax 
EndEnumeration

Import "Kernel32.lib"
  GetComputerNameExW(NameType, lpBuffer.s, nSize)
EndImport

Procedure.s GetComputerName(NameType = #ComputerNamePhysicalDnsFullyQualified)
  Protected r.s, size = 512
  r = Space(size)
  If GetComputerNameExW(NameType, r, @size) 
    ProcedureReturn Trim(r)
  EndIf 
EndProcedure

Debug GetComputerName()
Windows (x64)
Raspberry Pi OS (Arm64)
Rinzwind
Enthusiast
Enthusiast
Posts: 636
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Re: Import x86 only polink error

Post by Rinzwind »

Thanks!

Where does that underscore and @12 come from?
Tried dumpbin, got this
ordinal hint RVA name
481 1DE 0001A460 GetComputerNameExW

Help mentions callsize, but Googling shows nothing related. Call size = stack size for parameters? 3x4 = 12 bytes? Then why would it only need to be specified on 32bit? Just trying to get to know the reason behind it.

Aha, one way to get needed details (if there is some little tool somewhere else to do it let me know). I post it for others and myself if I ever need it again...
VS tool
link /dump /all "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\um\x86\kernel32.Lib" > c:\temp\t1-32.txt

328A2 _GetComputerNameExW@12
328A2 __imp__GetComputerNameExW@12

link /dump /all "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\um\x64\kernel32.Lib" > c:\temp\t1-64.txt

2E87A GetComputerNameExW
2E87A __imp_GetComputerNameExW

The help says "By default the imported function symbol is 'decorated' in the following way: _FunctionName@callsize", but doesn't mention that 64 bit works different?

Anyway KISS GetComputerNameExW it is. Would be nice to have some kind of alias construct which keeps using the lookup logic (so 32/64 bit compatible).

Code: Select all

Import "Kernel32.lib"
  GetComputerNameEx(NameType.i, lpBuffer.s, nSize.i) Alias "GetComputerNameExW"
EndImport
Last edited by Rinzwind on Tue Aug 11, 2020 6:02 am, edited 2 times in total.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Import x86 only polink error

Post by wilbert »

Rinzwind wrote:Where does that underscore and @12 come from?
Name mangling :wink:
https://en.wikipedia.org/wiki/Name_mangling
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply