bakke@plains.UUCP (Jeff Bakke) (12/09/89)
I have a problem that I hope someone could help me with. I am currently developing a Graphics library set for the PC using C and Assembler, but in doing so, I have created support in Assembler for most of the standard graphics modes and few non-standard. The problem that I have is that when a program is compiled to use this library of routines, all of the support routines for all the graphics modes (not just the ones that are required or used) have to be compiled into the program. Currently I am avoiding this problem by including conditional compiles, but I would like to be able to select which one is used in Run time. The question: Does anyone know how to set up a system of "drivers" or overlay type files in turbo c? Something like borland uses? As far as I can tell, I could simply compile each routine, remove all non-pertinent information to the execution, and save it. And then, allocate memory, load that modified .OBJ file, and execute it. But if the routine uses EXTERNAL references, then I'm stuck because of the dynamic memory problems. Is there anyway to avoid this or, at the least, could someone point me towards a reference on the format of .OBJ files so that I could find out how external references are fixed. Thanks for the help. Jeff Bakke bakke@plains.NoDak.edu
rob@prism.TMC.COM (12/10/89)
>Does anyone know how to set up a system of "drivers" or overlay type files >in turbo c? Something like borland uses? >As far as I can tell, I could simply compile each routine, remove all >non-pertinent information to the execution, and save it. And then, >allocate memory, load that modified .OBJ file, and execute it. But >if the routine uses EXTERNAL references, then I'm stuck because of the >dynamic memory problems. Is there anyway to avoid this or, at the >least, could someone point me towards a reference on the format of >.OBJ files so that I could find out how external references are >fixed. I successfully did something like this a while ago. My memory's fuzzy on the details, but the method was basically this: I compiled each 'driver' to a standalone .EXE file. Each driver had within it, a table which contained the addresses of all the routines in the driver. The 'host' program would load the driver into memory using the DOS load overlay function (a subfunction of the load and execute function). It would then make a call to the driver's entry point. The driver would do whatever initialization it needed and return a pointer to its table of routines. The host program could then call these routines as needed, and even unload the driver when it was done. The information needed to make this work (like the driver's entry point and the amount of memory it needs) is contained in the .EXE header, so you need to know the layout of that. Most DOS programmer's guides have this information. If the driver uses DOS for disk IO or memory allocation, you may also need to update the DOS Current PSP flag when you call the driver. The mechanics of doing this aren't well documented, but aren't really difficult either. This sounds messy, but it wasn't that hard to do; as I remember, it took only week or two to set up. My feeling is that it's a simpler method than attempting to modify and execute .OBJ files. It does, however, require that your driver be compilable to a standalone .EXE file. If your drivers currently make heavy use of globals in the calling program (which will no longer be there to link with) you may need to modify them.