F# IDE scripting support for accessing internal types in referenced assemblies - f#

Usually for non-scripting C#/F# project, one can specify a InternalsVisibleTo attribute in the dependency assembly and be able to get intellisense for its internal types in the IDE. But in F# scripting, how would I configure the dependency assembly with respect to the IDE I'm using in order to get intellisense for internal types? Of course in order for the script to run by fsi I assume I'd need something like
[assembly:InternalsVisibleTo("fsi")]
But in order to get the IDE support should I also specify every known IDE in the dependency assembly? That doesn't seem to scale very well.
I did a code search and found this where fsc, fsi, compiler service assembly, and their strong name versions, etc. are all specified, seemingly to accommodate IDEs. This is exactly what concerns me and I don't want to litter my assemblies with these. Is there a better way?

Related

Which are the differences between a bpl delphi expert and a dll delphi expert

I am working in a delphi IDE expert , now to avoid dependencies problems, i was thinking in rebuild this expert as a dll expert as was suggested in one of these answers, now my expert (compiled as bpl) access the Screen and Application global variables (instances of the Delphi IDE), so i was wondering if i compile my expert as a dll i can still accesing these variables and also i want to know which are the main differences between a bpl delphi expert and a dll delphi expert?
Should I compile my wizard as a DLL or a Package? Packages are easier to
load and unload without restarting the
IDE (and hence easier to debug), but
they can create unit naming conflicts
in the IDE. Conflicts happen when the
name a wizard's unit matches the name
of a unit in another loaded
design-time package. In this case,
both packages can not be loaded at the
same time. The recommended workaround
is to prefix all of your unit names
with a "unique" prefix. GExperts, for
example, uses "GX_" as the name prefix
for its units.
From this very good source about OTA: GExperts
When you access a global variable those would be global variables that are global to your DLL, not global to the main BDS.exe. I am not sure but I think your DLL would have its own Screen and Application global variable, if you linked in Forms, and the core of the VCL.
Those things which belong to the IDE itself are accessed through the Open Tools Api (OTA). I believe that you do not normally share any objects between the IDE your expert anyways, and if you were to try to do so, it would be problematic. Anything at all that you do that bypasses the OTA is going to be vulnerable to breaking in strange ways, especially in future versions of the IDE.
Dependency problems are of course a big reason to not use BPL based packages, but I think an even bigger reason is to maintain a complete separation between your tool's internals, and the internals of the IDE.
Remember that a DLL target, like an executable target, is statically linked. That is the core of the difference. If your expert provides functionality that uses the legal public documented OTA interfaces only, then moving to a DLL should be problem free. If you use some back door hacks that are possible with BPLs, then I can't advise you further.

which one is best for use in delphi i.e use of package or dll

I'd like to use a .dll with a delphi application, but I'm curious if a delphi package is more flexible than dll?
You can read this article on my Blog: "DLL's, BPL's Static and dynamic loading, and Packages in Runtime"; Is 's writed in Spanish but you can try the Automatic translation (on right part of the page).
Basically BPL is an extension of a DLL. It's a DLL with some things added.
(POSITIVE) If you use BPL's you can do more things with the DLL. More power. You can use RTTI (you must build your applicaction with runtime package for accesss RTTI).
(NEGATIVE) If you use BPL's with more powerfull, you can only use it with Delphi, no with other languages.
If you're sure that you only use it with Deplhi, I think that you must use BPL. Search samples about RTTI, RegisterClasses, GetClass method, LoadPackage (for dynamic load),...
Regards.
Escuse-me for my poor english. It's not my natural language.
Not knowing excactly what you mean, and believing you are a newbie (so I may omit some specialized aspects), and implying you know what a DLL is:
The first and foremost reason to build a package is authoring a design-time component.
You can do quite everything (well..almost...) that a package does just as well with DLLs -- except for the design-time stuff.
Additionally, you can package multiple compiled packages into one Borland Package Library (BPL file) without having the design-time features in mind. If you think deploying and runtime-binding one BPL is better than various DLLs, go for it. The primary purpose is design-time support, though.
Packages are special DLLs that can export classes, while DLLs can only export functions. Yes, you can write a DLL function that creates and instance of a given class, but you can't use a class declared in a DLL (unless using some hacks maybe), while you can use a class declared in a package directly. Packages "know" about Delphi object architecture, while DLLs don't. On the other end, DLLs can be used from any language able to use them, while packages are Delphi-specific.

F# powerpack and distribution

I need arbitrary precision rational numbers, which I'm given to understand are available in the F# powerpack. My question is about the mechanics of distribution; my program needs to be able to compile and run both on Windows/.Net and Linux/Mono at least, since I have potential users on both platforms. As I understand it, the best procedure is:
Download the powerpack .zip, not the installer.
Copy the DLL into my program directory.
Copy the accompanying license file into my program directory, to make sure everything is above board.
Declare references and go ahead and use the functions I need.
Ship the above files along with my source and binary, and since the DLL uses byte code, it will work fine on any platform.
Is this the correct procedure? Am I missing anything?
You're essentially correct, arbitrary precision rational numbers are available only in PowerPack (BigInteger is part of .NET 4.0, but rationals are still F# specific).
However, you'll also need to distribute your program with F# runtime redistributable (that is the FSharp.Core.dll assembly). It contains some basic F# types (such as types used to represent functions) that are not a part of standard .NET runtime.
More information about F# Redistributable Package is available at MSDN
You can download the FSharp.Core.dll redist from Microsoft Downloads.
When you add a reference to your project, the compiler includes the name and version of the referenced library in your application. When the application starts, the runtime tries to locate the library in various places. So, to deploy your application on both .NET and Mono, you'll need to (somehow) distribute your application together with FSharp.Core.dll and FSharp.PowerPack.dll.
The F# Redistributable and F# PowerPack installers place the library to GAC (Global Assembly Cache) which is shared by all .NET apps on the computer. On Mono, you can get the same result by using the gacutil tool (from command line). In that case, you need to copy them somewhere (anywhere) and run this tool. Your application will find them in the GAC.
Alternatively, if you place the assemblies to the same folder as your application (exe file) then both .NET and Mono should locate them correctly as well and it should work. I believe that this is discouraged for versioning reasons (e.g. the globally installed file can be easily updated), but I don't think the license prohibits this form of deployment.
It seems that for creating .NET/Mono redistributable, using the second technique would be easier (as it allows simple xcopy depoloyment).

Plugins system for Delphi application - bpl vs dll?

I'm writing delphi app which should have capability of loading plugins. I'm using JvPluginManager as plugin system/manager ;) Now, in the new plugin wizard they say it's better to use .bpl type plugins instead of .dll plugins ... What are the pros of this solution versus dll type plugins?
So far I've found only cons of this solution:
I have to put all the common interface units in separate package so that while loading plugins it won't throw any error about the other package containing common unit
if, let's say, one of plugin developers decides to uses some well-known unit (like synapse), which doesn't have runtime package by default, and the second plugin developer does the same, than bump... it's crash here ...
So, what are actually the pros of using bpls instead of dlls compiled with runtime packages?
Thanks in advance
Another disadvantage to BPL's. When you switch Delphi versions you will have to re-distribute new plugins. After many attempts at attempting to find the perfect plugin system, I ended up with COM and I have never regretted that decision. In a commercial application which has had the plugin requirement for over 8 years, the application has continued to move forward and yet some of the plugins that were released with the first iteration still exist in their ORIGINAL form.
If you choose this method, do yourself a favor and start with a simple interface and then add new interfaces upon it. You don't want to ever change your base interface, so keep it simple and sweet.
As Alexander said, a BPL is basically a DLL. But there are some conditions (from a not-so-short summary I made: http://wiki.freepascal.org/packages ):
A unit can only exist once in BPL's +Exe. This avoids duplication of state (twice the heapmanager and other global vars of system etc, VMT tables etc)
.BPL's can only USE other .BPLs.
This means that dynamic types like ansistring and IS/AS work properly over BPL interfaces.
Initialization/finalization are separate procedure and their initialization order is strictly controlled. For static dynamic loading this is simpler, for dynamic loading (plugin-like) all dependancies on units are checked .
Everything is essentially one big program, which means that the BPL's must be compiled with the same compiler version and RTL and depends on the versions other dependancies. It might be harder to make .BPL's to plugin to an existing EXE, since the Delphi version must match.
This also means that you must deliver .dcp's for (non Delphi) .BPLs the plugin .BPLs depend on
In short: if the plugin architecture is open, make it a DLL. Otherwise people have to have the exact same Delphi version to write plugins.
Hybrid is also possible. An higher level .BPL interface for functionality you factor out into .BPL yourself and selected devels, and a rock bottom procedure DLL interface for the rest.
A third option is using DLLs, but ordain Sharemem. Strings will work, multiple Delphi versions will work. Objects can work but are unsafe (e.g. I guess e.g. D2009 with an earlier version wouldn't work). Even other language users might be able to allocate over COM, not entirely excluding non Delphi.
Your first con is also a pro. If you replicate shared code in each dll the dlls get bigger and bigger. Even when using dlls you can prevent this by moving shared code in a separate dll.
Pros:
Types are shared. No TFont is not a TFont problem
Memory manager is shared. Strings and classes can be used as parameter between plugins without problems.
Cons:
Plugins can be built using Delphi or BCB only.
Plugins should use the same Delphi or BCB version.
Have you considerd using COM? COM makes it possible to share types, strings and classes and the plugins can be written in many programming languages.
I'm not familiar of JvPluginManager, but it depends on how you're going to use BPLs.
Basically, BPL - is just a usual DLL, but its initialization/finalization work is stripped from DllMain to separate functions: 'Initialize'/'Finalize'.
So, if you're going to use BPL like usual DLL, there are no cons that I'm aware of, only pros: there will be no more troubles with DllMain. That's all. The only difference.
But BPL in Delphi also provide a convient way to share code. This means great advantages (common memory manager, no duplicated code, etc, etc). So usual BPL does a lot more than "being just a DLL".
But this also means, that now your plugin system is limited to Delphi only (well, may be C++ Builder too). I.e. both plugins and exe MUST be compiled in the very same compiler to run smoothly.
If this is acceptable for you (i.e. no MS Visual Studio, no, sir, never) - then go ahead, you can use all power of BPLs.
P.S. But upgrading such BPLs plugins can be also a nightmare, if you do not design interface side carefully. In certain worst cases, you may need to recompile everything.
P.P.S. Like I said: I have no idea, how it is applied to plugins, created by JvPluginManager.
Avoid blp approach as you will have to ship a big bag of bpl with you software and thus, distribution will become bulky.
why do we use Delphi to compile small stand alone programs that just RUN anywhere without any runtime dependency. Using bpls means defeating this very purpose.
I don't know as to how comfortable you are with DLLs, but I would suggest you to use DLLs.
This will give other developers (who
may get interested in your software)
a chance to use any development
language (as long as that language
can spit out dll) to write their own
plugins that can be used in your
developed software.
Another thing is that you will be
saved from Delphi's vcl version
dependency tyranny. A major weak
point of Delphi till date.

Seq.generate_using is MIA

I'm trying to use the Seq.generate_using function but unfortunately, I don't seem to be able to find it. I thought it would be living here:
Microsoft.FSharp.Collections.Seq.generate_using
But it doesn't. I am getting the error listed below.
C:\Users\Owner\Documents\Visual Studio
2008\Projects\fsharp1\Program.fs(54,63):
error FS0039: The value, constructor,
namespace or type 'generate_using' is
not defined. A construct with this
name was found in
FSharp.PowerPack.dll, which contains
some modules and types that were
implicitly referenced in some previous
versions of F#. You may need to add an
explicit reference to this DLL in
order to compile this code.
According to the Sept 2008 CTP Release Notes:
The F# library is split into two
components. FSharp.Core.dll: Contains
the core F# libraries, which will be
stabilized and versioned infrequently.
FSharp.PowerPack.dll: Contains
additional useful F# libraries and
tools which will version more
frequently, and allow continued
innovation on top of the core F#
language and libraries.
Some methods in the Seq module were moved into the FSharp.PowerPack assembly, so you can only get those methods by doing the following:
If you're using Visual Studio, open your Solution Explorer, right-click on the project file, choose "Add Reference", and add "FSharp.PowerPack.dll".
If you're using a script file or fsi, then type #r "FSharp.PowerPack";; to load the assembly.
Now you should be able to call Seq.generate_using.
The #r "FSharp.PowerPack";; works for me but the addition of PowerPack to my solution does not. I am trying to use HashSet<>.

Resources