• Welcome to PlanetSquires Forums.
 

WinFBE on GitHub (July 2, 2016)

Started by Paul Squires, July 02, 2016, 10:44:21 PM

Previous topic - Next topic

José Roca

What it makes a big difference (using 192 DPI) is if the application is DPI aware or not. See capture.

Paul Squires

Yes, that is a pretty big difference.  :)

I have found that the CodeMax control that I used Jellyfish and my own custom built control for Firefly are a little more visually pleasing to the eye than Scintilla. I couldn't figure out just why until I noticed that it appears that Scintilla does not have as much spacing between it's lines than the other controls. I guess it makes the text a little more cramped together than I am used to. Maybe I am just getting old and set in my ways..... :)
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

I have run into a bit of a problem. I have been converting the project over to the FB way of doing things. I am trying to make a standalone object for each of the source files rather than include'ing them all off of the main file. I have been able to convert every file except for the CWindow class file. I am pretty sure that the problem is the NAMESPACE stuff. I guess I just don't understand it enough (yet) to be able to make the object file and corresponding header file. If this was going to be a standalone object (CWindow.o) that you would link to produce an EXE then how is it done? I will continue to plod away at this but my mind is a little mesmerized. It must be easy but right now I am not seeing it.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

And what happens with conditional code (#if... #endif)?

I never have used PB SLLs because they don't allow conditional code.

Paul Squires

Quote from: Jose Roca on July 04, 2016, 03:51:33 PM
And what happens with conditional code (#if... #endif)?

I never have used PB SLLs because they don't allow conditional code.


I assume that the library would access the target of the conditional operation either through whatever variables are defined within the module itself (eg. #DEFINE UNICODE, etc...). I assume the value if the target would have to known at compile time. I am thinking that in the case of CWindow where you have conditional defines for MDI support that you might have to implement dynamically rather than rely on a conditional at compile time. Maybe define an additional property for the class (BOOLEAN) that controls whether MDI is active. Remove the #IFDef and just do a tradition IF/THEN test on the property BOOLEAN and call the correct MDI or non-MDI routine. I guess that would also mean that you would need to compile code for both MDI and non-MDI cases into the library rather than excluding one or the other at compile time with a #Define. I'm just thinking out loud and typing so I may not be thinking of all the scenarios here.

I got basically no programming done last night because I had to reinstall my laptop.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

James Fuller

Paul,
  What advantages do you get with individual module .bas -> .c -> .obj link *.obj -> .exe  in normal every day coding?
I can see the advantage if you have 100's of individual files but .... with the judicious use of #include Onece and Private I can include every source file I've every written :)

James

Paul Squires

Hi James, yes of course you're right, for the everyday small project there is no real advantage. For larger projects the incremental compile time is greatly sped up if the object files already exist. Likewise, it promotes the use of header files with function/type definitions that aid in not having to always juggle around order to the files that you are Incude'ing into a main .bas file just to get it to compile. I guess what I'm saying is that I want to start to try to handle projects more like they do in the FB world just so I can be consistent with them. Either way, I am hoping that the new system is flexible enough to handle both styles of coding.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

James Fuller

#22
Paul,
  Been there done that with FreeBasic many years ago prior to Private.
  Sorry I don't believe Compile times on todays equipment are relevant.
  Maintenance on a big library is just too much of a PIA for me.

To get the best granularity each function needs to be compiled to an obj file.
When I first started I thought the linker was smart enough to just link in the functions used from the obj file.
Not so. All code from each obj file is included used or not if it is linked in.
Even a minor change to one obj module means recreating your library. How to tell versions apart.

The need to maintain TWO libraries 32/64.
With source it can be just just one.

In my opinion I don't think many Fb coders are aware of the Power of Private. I was not.
The Fb way to do things as you say is the least common denominator for Win32/64, Linux, And DOS.


James




Paul Squires

Thanks James, excellent commentary.

Here is a good explanation that confirms what you are saying:

Quote
If the library is a shared object or DLL, then everything in the library is loaded, but at run time. The cost in extra memory is (hopefully) offset by sharing the library (really, the code pages) between all the processes in memory that use that library. This is a big win for something like libc.so, less so for myreallyobscurelibrary.so. But you probably aren't asking about shared objects, really.

Static libraries are a simply a collection of individual object files, each the result of a separate compilation (or assembly), and possibly not even written in the same source language. Each object file has a number of exported symbols, and almost always a number of imported symbols.

The linker's job is to create a finished executable that has no remaining undefined imported symbols. (I'm lying, of course, if dynamic linking is allowed, but bear with me.) To do that, it starts with the modules named explicitly on the link command line (and possibly implicitly in its configuration) and assumes that any module named explicitly must be part of the finished executable. It then attempts to find definitions for all of the undefined symbols.

Usually, the named object modules expect to get symbols from some library such as libc.a.

In your example, you have a single module that calls the function a(), which will result in the linker looking for module that exports a().

You say that the library named A (on unix, probably libA.a) offers a() and b(), but you don't specify how. You implied that a() and b() do not call each other, which I will assume.

If libA.a was built from a.o and b.o where each defines the corresponding single function, then the linker will include a.o and ignore b.o.

However, if libA.a included ab.o that defined both a() and b() then it will include ab.o in the link, satisfying the need for a(), and including the unused function b().

As others have mentioned, there are linkers that are capable of splitting individual functions out of modules, and including only those that are actually used. In many cases, that is a safe thing to do. But it is usually safest to assume that your linker does not do that unless you have specific documentation.

Something else to be aware of is that most linkers make as few passes as they can through the files and libraries that are named on the command line, and build up their symbol table as they go. As a practical matter, this means that it is good practice to always specify libraries after all of the object modules on the link command line.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

Quote from: James Fuller on July 05, 2016, 11:23:18 AM
The need to maintain TWO libraries 32/64.
With source it can be just just one.

Ah, yes, I can see this as being a huge pain the butt. Likewise, if the use of PRIVATE was better known then the source code route would be most advantageous to most people. Also, using source files alleviates having to deal with COMMON between modules. I have learned also that classes when shared between modules can NOT have constructors or destructor. This also implies that you can give your class default member values when you create your TYPE. You basically need to have another function in your class that you explicitly call in your code after the instance of your class is created in order to initialize the values in your TYPE.

Having said all that, the use of modules does seem to introduce an added level of complexity that may not be beneficial in the long run. I have attempted to create a version of the editor project that is 100% based on a main file and then compiled object files for all other code. It works but it is not as intuitive as an all source code approach. I have noticed though that there are areas where I can create independently compiled object files but the added compile speed advantage is not really worth the trade-offs.

I am going to leave the functionality in the editor in case people want to pursue that type of code development. Large projects will benefit from it but for the most part I am thinking it may be the exception rather than the rule unless you are a purist who always develops code one way. Having the ability in the editor will also help those people who want to write and share libraries of compiled code without also having to share the source code (granted, you don't see much of this in the FB community or open source community in general).
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

#25
> In my opinion I don't think many Fb coders are aware of the Power of Private. I was not.

There is not a clear indication in the help file, that only says:

Quote
In procedure definitions, Private specifies that a procedure has internal linkage, meaning its name is not visible to external modules.

I discovered it because this post in the FB forum: http://www.freebasic.net/forum/viewtopic.php?t=23405

Quote
fbc already removes unused private procedures/variables, but that's pretty much it. There are no plans to improve this on the fbc side as far as I know, but of course with -gen gcc/llvm it will be done nevertheless (just not by fbc, but by gcc/llvm).

The "fbc already removes unused private procedures/variables" part is what pushed me to continue working with FB, that I had stopped because I didn't wanted having hello world type tests of more than 1 Mb. If you're going to use libraries, then Private no longer can be used.

Currently, CWindow has only conditional defines for MDI, but I have further plans, like an Ole Container control. There is one feature of the Ole Container that can only be activated at creation time, meaning that I would need to always include the code of this control, whether I may need it or not, or write a separate class for it.

I find the library system as outdated as using tabs in the source code to save some bytes of disk space (useful when we used floppy disks, but not today). I also prefer the use of "LIB" or "IMPORT" in the declares, instead of these annoying import libraries.


Paul Squires

Thanks Jose, points well received. I'm happy that you, me and James had this conversation today.

:)
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

Here is a little gold nugget I discovered today while browsing the Scintilla documentation. You can get a direct pointer to the internal Scintilla text buffer. The call returns a byte pointer but because the call sets up the buffer with a null terminating character, we can cast that pointer to a ZString Ptr allowing us to save the whole buffer without first having to copy it to a string variable.


         Dim psz As ZString Ptr
         
         Dim As Long f = Freefile
         Open "_test.txt" For Output As #f
         psz = Cast( ZString Ptr, SendMessageW(hEdit, SCI_GETCHARACTERPOINTER, 0, 0) )
         Print #f, *psz
         Close #f


Or, we could just manipulate the buffer byte-by-byte...


         Dim As Byte Ptr pByte = Cast( Byte Ptr, SendMessageW(hEdit, SCI_GETCHARACTERPOINTER, 0, 0) )
         Dim As Long nLen = SendMessageW(hEdit, SCI_GETTEXTLENGTH, 0, 0)
         
         Dim As Long f = Freefile
         Open "_test.txt" For Output As #f
         For i As Long = 0 To nLen - 1
            Print #f, Chr(*pByte);
            pByte += 1
         Next
         Close #f



Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

#28
Just a joke... or not?

Dear new FB user,

You come here looking for a BASIC compiler because you think that BASIC is the easiest language to learn and use. You're right, but we, the people that are making the compiler, are C programmers, and our life as programmers has been very rough, so we are going to make your programming experience with FB as nasty as we can.

We have implemented BYREF, but we aren't going to use it at all. No one of our translated API headers has a single BYREF parameter. Why to let you to just pass the variable name when we can force you to have to add a @ in front of it?

BASIC programmers are used to just write a declare with a LIB or IMPORT clause that let's them to call the function immediately, but that's too easy and, therefore, little professional. Instead, you have to make a .def file and an import library. But, of course, we aren't going to provide you all the tools you need. You will have to search the web to see if you find one that works. After reading about the subject, you find one of the recommended tools to make the .def file, but alas, poor Yorick!, it GPFs when you try it. You find the second recommended tool, but the linker doesn't like the library made with it, although it won't tell you why or what does not like. There is a third tool, but doesn't work with DLLs, so you have to download the Windows SDK to get the LIBs. Another little inconvenience is that the tool that works is only available in source code, so you have to learn C programming to compile it or beg a C programmer to do it for you. We never promised you a rose garden, did we?

If you're a foreigner that speak one of these strange foreign languages (we don't object to foreigners speaking a foreign language, but why don't speak the same foreign language all of them?), you're doomed. We have recently added unicode support, but only for null terminated strings. This way, you're going to feel the pain of ansi C programmers when have to deal with strings. BASIC, with its dynamic strings, makes it too easy. Real programmers have to allocate, deallocate and copy memory using pointers, and enjoy the joys of GPFs, buffer overruns and difficult programming.

The Unicode conversions will always use CP_ACP, without letting you to choose the code page, so if you really want to use unicode, forget automatic conversions and use the Windows API. These automatic conversions are only useful to those that don't need them and that think that unicode is simply a way to waste memory by adding a null in front of every character.

We are also going to force you to use CAST once or twice in almost every line of code. It is annoying, but that is the way that real programmers work. A guy even proposed more strict checking, but we thought that his proposals were a bit too sadistic.

"Abandon all hope, ye who enter here."

Paul Squires

BEST. POST. EVER.   :) :) :)

That just about sums it up!
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer