Page 1 of 1
Convert lib to dll?
Posted: Sun Jun 21, 2009 7:19 am
by PB
I'm sure I saw a post on how to convert a PureBasic lib (such as Gnozal's)
to a DLL, but can't find it now. Was I just dreaming? Or is it possible to do?
The aim is so old libs can be used with newer PureBasic versions without
them breaking, by making them DLLs instead of staying as old libraries.
Posted: Sun Jun 21, 2009 7:56 am
by Mistrel
PureBasic libraries are static linking. I'm no expert on the subject but I don't think it's possible.
Posted: Sun Jun 21, 2009 9:53 am
by srod
Sure, you just need to create a dll which wraps the functions in the library. When the dll is created, all the required user-lib functions will be statically linked into the dll.
However, it is not a question of how; more a question of whether you should?

Posted: Sun Jun 21, 2009 10:52 am
by PB
> you just need to create a dll which wraps the functions in the library
Ah yes, of course! Time to get working.
> a question of whether you should?
So you don't need to wait for the author to update their libs for new versions.
Posted: Sun Jun 21, 2009 11:04 am
by srod
You must bear in mind though that a lot of Tailbitten libraries will not work directly from a dll. At best you will need to modify your programs before they can use the lib in dll form.
For example, any function returning a string will need wrapping so that the dll fills a string buffer instead etc. (Using a global string as a return value will mean that the program is not threadsafe). This will mean that your client applications will need modifying in order to receive a string in this way.
Also, and more seriously perhaps, any user-lib function operating upon a window/gadget (through a window# or gadget#) in the client application will not work in a dll because the dll wrapper function will not be able to identify the gadget in question (the dll has it's own heap memory for gadget# etc.) So, for example, if the client app passes a gadget# of 1 in one of its function calls, then the dll will not be able to map this gadget# with the gadget created in the client application.
These problems do not exist when using the user-libs directly (not in dll form) because when statically linked they are using the same heap memory as the 'client' etc. in these cases.
The point is that some applications will need some quite drastic changes before they can use your dll - so you need to take care!

Posted: Sun Jun 21, 2009 12:17 pm
by Kaeru Gaman
srod wrote:Also, and more seriously perhaps, any user-lib function operating upon a window/gadget in the client application will not work in a dll because the dll wrapper function will not be able to identify the gadget in question (the dll has it's own heap memory for gadget# etc.) So, for example, if the client app passes a gadget# of 1 in one of its function calls, then the dll will not be able to map this gadget# with the gadget created in the client application.
just out of curiosity...
when a function doesn't expect Gadget# but GadgetID(#), it would work, wouldn't it?
Posted: Sun Jun 21, 2009 12:22 pm
by srod
In a dll, yes.
Posted: Mon Jun 22, 2009 2:23 am
by jack
couldn't you extract the objects from the static lib and then link them into a dll?
I know you can do it with gcc/g++ but this is MS VC
Posted: Mon Jun 22, 2009 10:13 am
by srod
jack wrote:couldn't you extract the objects from the static lib and then link them into a dll?
I know you can do it with gcc/g++ but this is MS VC
Yes, by just creating the aforementioned wrapper. Let the linker do all the work.
If you are thinking about phycisally reaching into the static lib and pulling out all the required code then, well, complicated by the fact that the PB user-libs are not simple COFF object files. Worse though, a COFF object file will generally contain a million and one dependences (other COFF files) which can only be resolved at link time and only then by a suitable linker. So, no escaping the use of a linker which really leads you back to the creation of a simple wrapper. Best way all round.

Posted: Tue Jun 23, 2009 2:52 am
by jack
isn't the linker responsible in finding all the dependecies when building a dll?
for example, in gcc you can do this
(where the *.o are the object files)
and it will create libname.dll.
I will look into it when I am not so tired
Posted: Tue Jun 23, 2009 5:51 am
by lexvictory
@jack: yes, in theory you could do something like that, however as srod mentioned, pb userlibs are not plain coff files (.obj, .lib).
Also, doing that would probably NOT solve the problem that is trying to be avoided, i.e. using a lib designed for an older version of PB. Though it might, apart from the gadgets, windows, etc that srod mentioned.
To do it, your would have to extract ALL the PB commands and internal procedures (eg. PeekS, Str, SYS_AllocateString) and link them in. Which means you may as well create the wrapper DLL in PB code, as the extraction would be a much mode complicated code.
@srod: I probably just rephrased what u said, didn't I?

Posted: Tue Jun 23, 2009 9:59 am
by srod
isn't the linker responsible in finding all the dependecies when building a dll?
Okay, but your original post seemed to suggest some way of doing this without a linker!

When looking to resolve dependencies, the linker will of course only look in the object files which you pass it via the command line or some command file etc. So, the answer to your question is, yes ... and no! It is certainly responsible for extracting all relevant code sections etc. from the various object files, but it will not trawl through files it is not told to consider. The other thing to consider is that general MSCOFF object files can contain a lot more symbols in their respective symbol tables than you would want exporting in the final dll - as dictated, to a lot of the extent, by the back-end assembler. That is, if you did have some linker based tool for building a dll from a user-lib; then this tool would need additional information to know exactly which functions to export? Exporting every symbol listed within an individual symbol table and which refers to an address in a code section would invariably result in far more functions being exported than you would otherwise wish. Heck, it may even not export some functions that you would wish exporting!

Different assemblers build COFF files in different ways and make use of the symbol tables in different ways. Admittedly, we would probably be okay on that score with Purebasic as FASM is pretty well behaved in that department.
In theory, because of the way Purebasic user-libs are structured, you could create a tool which pulled out the COFF .lib file from a given user-lib and then proceeded to extract all dependent .lib files from all other required user-libs (this information is embedded within each user-lib). It would then need to examine the symbol tables from the original .lib file in order to construct a likely looking list of exports (or take this information from the user via the command line). The tool would then call the linker passing this list of .lib files plus all required system libraries plus a list of symbols to be exported for linking into the final dll.
Simpler to create a wrapper don't you think?
