• Welcome to PlanetSquires Forums.
 

CWindow Release Candidate 31

Started by José Roca, August 06, 2017, 02:51:36 PM

Previous topic - Next topic

Paul Squires

Quote from: Jose Roca on September 07, 2017, 04:20:43 PM
For overloaded methods, when NET creates the COM callable wrapper it adds an underscore and an ordinal to each one. Therefore, the first overloaded Append method of the "System.Text.StringBuilder" class is called "Append", but the second one "Append_2" and so on.


'#CONSOLE ON
#define UNICODE
#INCLUDE ONCE "windows.bi"
#INCLUDE ONCE "Afx/CCLRHost.inc"
USING Afx

' // Create an instance of the CCLRHost class
DIM pCLRHost AS CCLRHost

' // Create an instance of the .NET StrigBuilder class
DIM pDisp AS CDispInvoke = pCLRHost.CreateInstance ("mscorlib", "System.Text.StringBuilder")
IF pDisp.DispPtr = NULL THEN END

pDisp.Invoke("Append_3", 1, CVAR("Hello"))
pDisp.Invoke("Append_3", 1, CVAR(" World!"))
print pDisp.Invoke("ToString").ToStr

PRINT
PRINT "Press any key..."
SLEEP


As we are using Automation, the call to pDisp.Invoke("ToString") does not return a string, but a VARIANT. Therefore, we have to use pDisp.Invoke("ToString").ToStr to convert the returned variant to a string.

I could envision down the road a FB class that encapsulates this code to make it transparent to the programmer. A class with overloaded functions that in turn call the necessary version of the underscored .net function (append_1, append_2, append_3, etc).

I guess you only need to create instance of runtime once at start of program and even make it global so that you could call it throughout your program.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

....this is blowing my mind it is so cool.   :)
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

#77
Quote
I am surprised with how fast it is even as you say that it must create an instance and use dispatch interface. I added 100,000 strings in about a second or so.

And CVAR("xxx string") is also creating and destroying a temporay instance of the CVAR class, that has to allocate the string as a BSTR. We could gain some speed manipulating the variants directly, but that will be harder to code.

Quote
Is the creating of an instance of the class a time consuming process? Seems to me based on my limited tests that everything runs half decently fast as it is.

Looks like it is a fast process. Anyway, it is done only once, so the overhead that must worry us is the one of calling the methods using Automation. It will never be as fast as a low-level COM server, but for many tasks it will be acceptable. Of course, the purpose of my research is not to use the .NET framework instead of other techniques, but to allow to use it when we find it convenient. For example, I won't use "System.Net.WebClient" to download a file, but CWinHTTP or WinInet, but we really need to write our own code to support stacks when we can use System.Collections.Stack"? This is not something that needs raw speed.


José Roca

#78
Quote
I guess you only need to create instance of runtime once at start of program and even make it global so that you could call it throughout your program.

As I have noted in a previous post, I have used a class just to make it easier to use the code, but only an instance of the class can be created because the CLR runtime can only be loaded once in the same process. This means that we only need to create an instance of the CCLRHost class per process and use it to create instances of the classes of the .NET assemblies.

José Roca

Quote
I could envision down the road a FB class that encapsulates this code to make it transparent to the programmer. A class with overloaded functions that in turn call the necessary version of the underscored .net function (append_1, append_2, append_3, etc).

I guess you only need to create instance of runtime once at start of program and even make it global so that you could call it throughout your program.

As I dislike the use of globals (they are poison to write reusable code), you can pass the pointer of the CCLRHost class as a parameter.

José Roca

In the constructor of the CCLRHost class I'm using "v4.0.30319", which is the highest version installed in my computer, as the default value It can be overriden by passing another version.

I will see if I can write a wrapper function that returns the highest version installed in a computer.

Paul Squires

I noticed that hard coded path. I wonder if you could use the code at the following link to query the Registry to get the highest installed net version.
https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

You could also query the "InstallPath" key.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

Looking at the registry of my computer I see that the version installed is 4.7.02053, although the name of InstallPath remains being "C:\Windows\Microsoft.NET\FrameWork64\v4.0.30319\".

And what happens if the computer is only 32 bit? Will the name be "C:\Windows\Microsoft.NET\FrameWork\v4.0.30319\"?

It's odd that Windows does not provide a function to return it.

José Roca

Seems that we have to use "v4.0.30319" and .NET will use the version found there (apparently it wants the name of the subfolder instead of the version installed). If I change that value to "v4.7.02053" it does not work. Guess that this value will be valid until version 5. One problem less :)


Paul Squires

Quote from: Jose Roca on September 07, 2017, 09:14:08 PM
Looking at the registry of my computer I see that the version installed is 4.7.02053, although the name of InstallPath remains being "C:\Windows\Microsoft.NET\FrameWork64\v4.0.30319\".

And what happens if the computer is only 32 bit? Will the name be "C:\Windows\Microsoft.NET\FrameWork\v4.0.30319\"?

It's odd that Windows does not provide a function to return it.

On my 64bit Windows 10 laptop I have both folders.... FrameWork and FrameWork64. On my 32 Windows 7 laptop I only have FrameWork.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

#85
The ICLRMetaHost interface as a method called EnumerateInstalledRuntimes. I will try to use it and see what it returns.

José Roca

Well, I don't see any need to search for complications. It seems that what matters is the name of the subfolder where it is installed.

v1.0.3705 - not available in 64 bit
v1.1.4322 - not available in 64 bit
v2.0.50727 - Net Framework 2
v3.0 - Net Framework 3
v3.5 - Net Framework 3.5
v4.0.30319 - Net Framework 4


Paul Squires

#87
So I guess you query Windows to see if you are running on 32 or 64 and then pick either the FrameWork or FrameWork64 subfolders, I guess?
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Pierre Bellisle

#88
-

José Roca

#89
Quote from: Paul Squires on September 07, 2017, 10:26:40 PM
So I guess you query Windows to see if you are running on 32 or 64 and then pick either the FrameWork or FrameWork64 subfolders, I guess?

No. We only need to pass "v4.0.30319" to support the .NET Framework 4. It works both with 32 and 64 bit. NET will look in the "Framework" subfolder if the application is 32 bit and in "Framework64" if it is 64 bit. This makes it easier to use. What I don't know is why they don't explain it.

Notice that no matter which version you have installed, the subfolder is called "v4.0.30319". and it works if we pass this value, whereas it does not work if we pass e.g. "v4.7.02053".