Undefined reference to '{function_name}'

Started by chalky, June 11, 2024, 16:33:58

Previous topic - Next topic


The following:

Extern "win32"
    Function CopyMemory:Long(hpvDest:String,hpvSource:String,cbCopy:Long)
End Extern

fails with:

undefined reference to 'CopyMemory@16'
during compilation. Similarly, the following:

Extern "win32"
    Function ClosePrinter:Long(hPrinter:Long)
    Function IsBadStringPtrByLong:Long(lpsz:Long,ucchMax:Long)
    Function OpenPrinter:Long(pPrinterName:String,phPrinter:Long,pDefault:TPrinterDefaults)
    Function GetPrinterApi:Long(hPrinter:Long,Level:Long,Buffer:Long,pbSize:Long,pbSizeNeeded:Long)
End Extern

all fail too with:

undefined reference to 'ClosePrinter@8'
undefined reference to 'IsBadStringPtrByLong@40'
undefined reference to 'OpenPrinter@16'
undefined reference to 'GetPrinterApi@40'

I remember having this issue several years ago, but cannot remember how/if I ever got round it.  Can anyone help me with what I need to do to get it to work?


The compiler has failed to link against whatever library or share library you are trying to link against.
Make sure that the library name is in compiler/linker command line options.
Make sure that the library is is correct, and exports those functions.
Make sure that the library is in the compiler/linker's search path.
Make sure that the linking order for all libraries are correct. Some libraries require that it's dependencies are linked to the application first. 


Thank you dawlane.

I have modified my code to manually load/check the function(s). However, I have clearly done something wrong, as [for example] the following compiles fine but fails to work:


Type TDevMode
    Field dmDeviceName:String
    Field dmSpecVersion:Int
    Field dmDriverVersion:Int
    Field dmSize:Int
    Field dmDriverExtra:Int
    Field dmFields:Long
    Field dmOrientation:Int
    Field dmPaperSize:Int
    Field dmPaperLength:Int
    Field dmPaperWidth:Int
    Field dmScale:Int
    Field dmCopies:Int
    Field dmDefaultSource:Int
    Field dmPrintQuality:Int
    Field dmColor:Int
    Field dmDuplex:Int
    Field dmYResolution:Int
    Field dmTTOption:Int
    Field dmCollate:Int
    Field dmFormName:String
    Field dmLogPixels:Int
    Field dmBitsPerPel:Long
    Field dmPelsWidth:Long
    Field dmPelsHeight:Long
    Field dmDisplayFlags:Long
    Field dmDisplayFrequency:Long

Type TPrinterDefaults
    Field pDatatype:String
    Field pDevMode:TDevMode=New TDevMode
    Field DesiredAccess:Long

Local OpenPrinter:Long(pPrinterName:String,phPrinter:Long Var,pDefault:TPrinterDefaults) "win32"
Local winspool:Long=LoadLibraryA("winspool.drv")

If winspool Then
   If Not OpenPrinter Then
       Print "Library error!"

Local pDef:TPrinterDefaults=New TPrinterDefaults
Local pHnd:Long
Local rVal:Long


rVal=OpenPrinter("CutePDF Writer",pHnd,pDef)
Print rVal
Print pHnd

as rVal always equals 0, indicating the call has failed.

Any guidance on what I've done wrong would be much appreciated.


Quote from: chalky on June 12, 2024, 13:40:27Local OpenPrinter:Long(pPrinterName:String,phPrinter:Long Var,pDefault:TPrinterDefaults) "win32"
Guess this is the problem.

Has it been declared as Extern?
Are the parameter types correct?
Is the return type an actual long type or a pointer to the function?
Should it use the Local keyword?

Quote from: chalky on June 12, 2024, 13:40:27OpenPrinter=GetProcAddress(winspool,"OpenPrinterA")
Then there's this. Which would clash with the former.

Read everything in the advanced topics.


Thanks again dawlane.

I tried running the code Henri posted in the blitzcoder thread you linked to, but it refuses to compile due to an "Unable to convert from 'Int' to 'Byte Ptr'" error:


Global lib:Byte Ptr = LoadLibraryA("user32")  <-- Unable to convert from 'Int' to 'Byte Ptr'

If Not lib
    DebugLog "LoadLibrary failed !"
    DebugLog "OK!"

Local func:Byte Ptr = GetProcWin32("CopyIcon")

Function GetProcWin32:Byte Ptr( proc:String )
    Local p:Byte Ptr = GetProcAddress( lib, proc )
    If Not p Then Print "Error: " + proc; End

    Return p

The thread on that site refers to NG whereas I am trying to get this to work on vanilla BlitzMax - is that why I cannot get it to compile?

Sorry - I clearly have a lot to learn here...


Doesn't matter - I have taken a different approach which no longer requires any external function definitions...