Page 2 of 2

Re: External .LIB compiles with ASM Backend, but not C Backend

Posted: Fri Sep 29, 2023 8:41 pm
by idle
Yes great job Yuki.

@joe you're not loosing anything by opening dll with late binding it just requires more code and you can also exit gracefully if you can't find the dll .

The only reason to use an import lib is that you don't have to change your code should you wish to link the static lib later sometimes its not practicable as you found and then there's often tons of unresolved symbols to resolve.

I think it's a bug, Pb c backend is handing the import off to the assembler but it doesn't like the mangled symbol asm(?....)

Re: External .LIB compiles with ASM Backend, but not C Backend

Posted: Sat Sep 30, 2023 12:34 am
by yuki
@idle has nicely summed up the (dis)advantages to this approach.

Though it tends to take more LOC, I've started defaulting to lazy loading most DLLs. Part of this is because I very often need to polyfill newer OS features or gracefully degrade on older platforms. Another part of it being that I often call into OOP C++ libraries with heavy name mangling and thiscall functions, so I'd end up wrapping over most things anyway.

By hiding the underlying library, it can be useful if you ever need to replace the library or go cross-platform where the library isn't available. Though, this isn't applicable in your case (being a product-centric plugin, with a specific library demanded).

It can aid in testing as well (particularly with a few handy macros), since you can quite easily mock/intercept.

Re: External .LIB compiles with ASM Backend, but not C Backend

Posted: Sat Sep 30, 2023 6:21 am
by juergenkulow
Functions and procedures should start with _ or a to z or A to Z, even in Take Command, jpsoft.(takecmd.lib)

Code: Select all

; Modify DLL function _f() to ?f() Windows x64
ProcedureDLL _f()
  ProcedureReturn 4711;
EndProcedure

; C Backend pbcompilerc d:\_f.pb /DLL /EXE D:\dll.dll /commented
; PureBasic.def: "?f"="f__f"

; ASM Backend pbcompiler d:\_f.pb /DLL /EXE D:\dll.dll /commented
; PureBasic.def: "?f"="_Procedure0"

; /REASM 
; polib /MACHINE:X64 D:\dll.dll  /OUT:D:\dll.lib

Code: Select all

; Call ?f() in D:\dll.dll 
PrototypeC _p()
Global myf._p 
dll = OpenLibrary(#PB_Any, "D:\dll.dll")
Debug dll
If Not dll
  MessageRequester("Fatal Error:", "Failed to load library.")
  End
EndIf
ExamineLibraryFunctions(dll)
Debug NextLibraryFunction()
Debug LibraryFunctionName() 
myf = GetFunction(dll, "?f")
If Not myf
  MessageRequester("Fatal Error", "Failed to load ?f function.")
  End
EndIf 
a=myf()
Debug a

; // a=myf()
; integer rr4=g_myf();
; v_a=rr4;

; ; a=myf()
;   CALL   qword [v_myf]
;   MOV    qword [v_a],rax

Code: Select all

; call ?f Windows 
ImportC "D:\dll.lib"
  myf() As "?f"
EndImport

a=myf() 
Debug a 

; C Backend
; integer f_myf() asm("?f");
; C:\Users\ADMINI~1\AppData\Local\Temp\cc6O8qho.s:122: Error: invalid character '?' before operand 1
; 	call	?f
; 	movq	%rax, -8(%rbp)

; ASM Backend x64: 4711
; ; a=myf() 
;   CALL   ?f
;   MOV    qword [v_a],rax
If someone has an elegant idea, he can show the idea at the last program.