Difference between revisions of "Using Pascal Libraries with .NET and Mono/it"

From Lazarus wiki
Jump to navigationJump to search
m (Fixed syntax highlighting)
 
(14 intermediate revisions by 4 users not shown)
Line 3: Line 3:
 
== Introduzione ==
 
== Introduzione ==
  
Con .NET framework, Microsoft ha fornito una eccellente compatibilità per il codice "unmanaged" (non gestito). Se il termine "codice non gestito" sembra evocare qualcosa di selvaggio e pericoloso, esso rappresenta solo il cosiddetto codice "legacy" nella forma delle lbrerie native di Windows. Il progetto [http://www.mono-project.com/Main_Page Mono] comprende un analogo supporto per le librerie native di Linux e OS X. Questo significa che si possono compilare librerie con Free Pascal e usarle con applicazioni .NET in Windows e con applicazioni Mono in Linux e OS X.
+
Con .NET framework, Microsoft ha fornito una eccellente compatibilità per il codice "unmanaged" (non gestito). Se il termine "codice non gestito" sembra evocare qualcosa di selvaggio e pericoloso, esso rappresenta solo il cosiddetto codice "legacy" nella forma delle lbrerie native di Windows. Il progetto [http://www.mono-project.com/Main_Page Mono] comprende un analogo supporto per le librerie native di Linux e macOS. Questo significa che si possono compilare librerie con Free Pascal e usarle con applicazioni .NET in Windows e con applicazioni Mono in Linux e macOS.
  
 
== Una semplice libreria Pascal ==
 
== Una semplice libreria Pascal ==
Line 9: Line 9:
 
Copiare e salvare il seguente codice Pascal nel file SimpleLib.pas:
 
Copiare e salvare il seguente codice Pascal nel file SimpleLib.pas:
  
<pre>
+
<syntaxhighlight lang=pascal>
 
library SimpleLib;
 
library SimpleLib;
  
Line 23: Line 23:
  
 
exports
 
exports
{$IFDEF DARWIN}  {OS X entry points}
+
{$IFDEF DARWIN}  {macOS entry points}
 
   MySucc name '_MySucc',
 
   MySucc name '_MySucc',
 
   MyPred name '_MyPred',
 
   MyPred name '_MyPred',
Line 31: Line 31:
  
 
end.
 
end.
</pre>
+
</syntaxhighlight>
  
Notare la direttiva condizionale per compilazione su OS X (DARWIN). Apparentemente il linker dinamico di OS X cerca un punto d'ingresso alla libreria che inizi con un underscore.
+
Notare la direttiva condizionale per compilazione su macOS (Darwin). Apparentemente il linker dinamico di macOS cerca un punto d'ingresso alla libreria che inizi con un underscore.
  
 
Ora compilare la libreria con Free Pascal:
 
Ora compilare la libreria con Free Pascal:
Line 39: Line 39:
 
<pre> fpc -Sd SimpleLib.pas</pre>
 
<pre> fpc -Sd SimpleLib.pas</pre>
  
In Windows, verrà creato il file simplelib.dll. In OS X, verrà creato il file libsimplelib.dylib. In Linux, this will create file simplelib.so. On OS X and Linux, rename the compiled library file to simplelib.dll:
+
In Windows, verrà creato il file simplelib.dll. In macOS, verrà creato il file libsimplelib.dylib. In Linux, this will create file simplelib.so. On macOS and Linux, rename the compiled library file to simplelib.dll:
  
 
<pre> mv libsimplelib.dylib simplelib.dll</pre>
 
<pre> mv libsimplelib.dylib simplelib.dll</pre>
Line 45: Line 45:
 
== Una semplice app VB.NET ==
 
== Una semplice app VB.NET ==
  
Copare e salvare questo codice VB.NET nel file TestLib.vb:
+
Copiare e salvare questo codice VB.NET nel file TestLib.vb:
  
<pre>
+
<syntaxhighlight lang=vb>
 
Imports System
 
Imports System
 
Imports System.Runtime.InteropServices
 
Imports System.Runtime.InteropServices
Line 82: Line 82:
  
 
End Class  'TestLib
 
End Class  'TestLib
</pre>
+
</syntaxhighlight>
  
 
Se .NET framework è installato in Windows, si può compilare il codice così:
 
Se .NET framework è installato in Windows, si può compilare il codice così:
Line 100: Line 100:
 
Questo è l'equivalente codice per C#. Copiarlo e salvarlo nel file TestLib.cs.
 
Questo è l'equivalente codice per C#. Copiarlo e salvarlo nel file TestLib.cs.
  
<pre>
+
<syntaxhighlight lang=c#>
 
using System;
 
using System;
 
using System.Runtime.InteropServices;
 
using System.Runtime.InteropServices;
Line 134: Line 134:
 
   }
 
   }
 
}
 
}
</pre>
+
</syntaxhighlight>
  
 
Con .NET, si può compilarlo così:
 
Con .NET, si può compilarlo così:
Line 148: Line 148:
 
== Una semplice app Pascal utilizzando Oxygene ==
 
== Una semplice app Pascal utilizzando Oxygene ==
  
Copiae e salvare il seguente codice Pascal nel file TestLib.pas:
+
Copiare e salvare il seguente codice Pascal nel file TestLib.pas:
  
<pre>
+
<syntaxhighlight lang=pascal>
 
namespace TestLib;
 
namespace TestLib;
  
Line 193: Line 193:
  
 
end.
 
end.
</pre>
+
</syntaxhighlight>
  
 
Il compilatore free Oxygene Object Pascal è disponbile qui [http://www.remobjects.com RemObjects Software].
 
Il compilatore free Oxygene Object Pascal è disponbile qui [http://www.remobjects.com RemObjects Software].
Line 221: Line 221:
 
<pre> mono TestLib.exe</pre>
 
<pre> mono TestLib.exe</pre>
  
Mono cercherà anche il file simplelib.dll -- e questo è il motivo per cui è stata rinominata la libreria compilata in Linux e OS X.
+
Mono cercherà anche il file simplelib.dll -- e questo è il motivo per cui è stata rinominata la libreria compilata in Linux e macOS.
  
Notare che i files ".exe" di .NET/Mono non contengono codice compilato nativo. Invece, contengono bytecode eseguito da .NET/Mono a runtime. Come risultato, si può prendere un file .NET .exe creato in Windows ed eseguirlo con Mono su OS X e Linux (e viceversa) senza ricompilarlo. Si <I>dovrà</I> ricompilare le librerie Pascal su ogni piattforma che si vuole supportare.
+
Notare che i files ".exe" di .NET/Mono non contengono codice compilato nativo. Invece, contengono bytecode eseguito da .NET/Mono a runtime. Come risultato, si può prendere un file .NET .exe creato in Windows ed eseguirlo con Mono su macOS e Linux (e viceversa) senza ricompilarlo. Si <I>dovrà</I> ricompilare le librerie Pascal su ogni piattforma che si vuole supportare.
  
== When to use native libraries with .NET/Mono ==
+
== Quando usare librerie native con .NET/Mono ==
  
Why not just code everything in VB.NET or C#? There are several situations where this might not be a  good idea:
+
Perché non scrivere semplicemente tutto il codice in VB.NET o C#? Ci sono diverse situazioni in cui questa può non essere una buona idea:
  
* When you have a large or complicated Pascal codebase that you don't want to rewrite (and re-debug) in C#.
+
* quando si ha un lungo o complesso codice Pascal che non si vuole riscrivere (e ricorreggere) in C#;
* When you have native libraries that need to be used by both native and .NET/Mono apps.
+
* quando si hanno librerie native che devono essere utilizzate da apps sia native, sia .NET/Mono;
* When there are performance reasons (presumably compiled FPC or Delphi native code is faster than the equivalent compiled bytecode run under .NET/Mono).
+
* quando ci sono motivi di prestazioni (presumilmente codice compilato in FPC o Delphi è più veloce di quello equivalente compilato sotto .NET/Mono);
* When you need low-level operating system access not available easily with .NET/Mono.
+
* quando è necessario un accesso a basso livello al sistema operativo, non facilmente disponibile con .NET/Mono;
* When you need to quickly develop code in a language you're more proficient in for a multi-developer .NET/Mono project.
+
* quando è necessario sviluppare codice velocemente in un linguaggio che  you're more proficient in for a multi-developer .NET/Mono project.
  
== Mono tips ==
+
== Appunti Mono ==
  
'''1.''' Since Visual Basic is pretty foreign to Linux and OS X, you'll probably want to develop .NET and Mono apps using C#, which is similar to C++ (and Object Pascal). Or use the Oxygene compiler and develop your .NET and Mono apps with familiar Object Pascal.
+
'''1.''' Poiché Visual Basic è un perfetto sconosciuto a Linux e macOS, probabilmente si vorrà sviluppare apps .NET e Mono utilizzando C#, che è simile a C++ (e Object Pascal). O usare il compilatore Oxygene e sviluppare apps .NET e Mono con un Object Pascal familiare.
  
'''2.''' Mono on OS X includes a script for uninstalling it. You can run this script before installing a newer version of Mono:
+
'''2.''' Mono in macOS comprende uno script per la disinstallazione. E' bene eseguire questo script prima di installare una nuova versione di Mono:
  
* In Finder, navigate to /Library/Receipts.
+
* In Finder, navigare fino a /Library/Receipts.
* Ctrl+click on MonoFramework.pkg and choose Show Package Contents from the popup menu.
+
* Ctrl+click su MonoFramework.pkg e scegliere Show Package Contents dal menu popup.
* Double-click the Contents folder.
+
* Doppio-click su Contents folder.
* Double-click the Resources folder.
+
* Doppio-click su Resources folder.
* Drag a copy of uninstallMono.sh to the desktop.
+
* Trascinare una copia di uninstallMono.sh sul desktop.
* Open a Terminal window.
+
* Aprire una finestra Terminal.
 
* cd desktop
 
* cd desktop
* sudo ./uninstallMono.sh and enter your password.
+
* sudo ./uninstallMono.sh e inserire la password.
  
'''3'''. In general, don't use any Lazarus units in your libraries. Libraries usually don't have a user interface. Confine your use to Free Pascal units like System, SysUtils, StrUtils, DateUtils, Classes, Variants and Math.
+
'''3'''. In generale, non utilizzare units Lazarus nelle librerie. Le librerie generalmente non hanno una interfaccia utente. Confine your use to Free Pascal units like System, SysUtils, StrUtils, DateUtils, Classes, Variants and Math.
  
'''4.''' If you need a user interface to go with your library, program it as a Windows Forms application. Here's a simple form example. Copy and save this code to file MyForm.cs.
+
'''4.''' Se si ha bisogno di una interfaccia utente per operare con le librerie, si programmi come un'applicazione Windows Forms. Si riporta di seguito un semplice esempio di form. Copiare e salvare questo codice nel file MyForm.cs.
  
<pre>
+
<syntaxhighlight lang=vb>
 
using System;
 
using System;
 
using System.Windows.Forms;
 
using System.Windows.Forms;
Line 288: Line 288:
 
   }
 
   }
 
}
 
}
</pre>
+
</syntaxhighlight>
  
Compile this code on Mono as follows:
+
Compilare questo codice con Mono così:
  
 
<pre> mcs -r:System.Windows.Forms MyForm.cs</pre>
 
<pre> mcs -r:System.Windows.Forms MyForm.cs</pre>
Line 298: Line 298:
 
<pre> mono MyForm.exe</pre>
 
<pre> mono MyForm.exe</pre>
  
On OS X, you can also create a normal app bundle using the macpack utility:
+
In macOS, si può anche creare una normale app bundle utilizzando l'utility macpack:
  
 
<pre> macpack -n MyForm -m winforms MyForm.exe</pre>
 
<pre> macpack -n MyForm -m winforms MyForm.exe</pre>
  
This creates the MyForm.app bundle, which can be double-clicked, dropped onto the Dock, etc.
+
che crea MyForm.app bundle, che può essere double-clicked, dropped onto the Dock, etc.
  
'''5.''' On Linux and OS X, Mono now includes MonoDevelop, a simple IDE for editing and compiling code.
+
'''5.''' Su Linux e macOS, Mono ora comprende MonoDevelop, una semplice IDE per l'editing e la compilazione del codice.
  
 
'''6.''' If you have any questions or comments about using Pascal libraries with .NET or Mono, please post them to the Lazarus forum.
 
'''6.''' If you have any questions or comments about using Pascal libraries with .NET or Mono, please post them to the Lazarus forum.

Latest revision as of 08:17, 4 March 2020

English (en) | italiano (it) | 日本語 (ja)

Introduzione

Con .NET framework, Microsoft ha fornito una eccellente compatibilità per il codice "unmanaged" (non gestito). Se il termine "codice non gestito" sembra evocare qualcosa di selvaggio e pericoloso, esso rappresenta solo il cosiddetto codice "legacy" nella forma delle lbrerie native di Windows. Il progetto Mono comprende un analogo supporto per le librerie native di Linux e macOS. Questo significa che si possono compilare librerie con Free Pascal e usarle con applicazioni .NET in Windows e con applicazioni Mono in Linux e macOS.

Una semplice libreria Pascal

Copiare e salvare il seguente codice Pascal nel file SimpleLib.pas:

library SimpleLib;

function MySucc(AVal : Int64) : Int64; stdcall;
begin
  Result := System.Succ(AVal);
end;

function MyPred(AVal : Int64) : Int64; stdcall;
begin
  Result := System.Pred(AVal);
end;

exports
{$IFDEF DARWIN}  {macOS entry points}
  MySucc name '_MySucc',
  MyPred name '_MyPred',
{$ENDIF}
  MySucc,
  MyPred;

end.

Notare la direttiva condizionale per compilazione su macOS (Darwin). Apparentemente il linker dinamico di macOS cerca un punto d'ingresso alla libreria che inizi con un underscore.

Ora compilare la libreria con Free Pascal:

 fpc -Sd SimpleLib.pas

In Windows, verrà creato il file simplelib.dll. In macOS, verrà creato il file libsimplelib.dylib. In Linux, this will create file simplelib.so. On macOS and Linux, rename the compiled library file to simplelib.dll:

 mv libsimplelib.dylib simplelib.dll

Una semplice app VB.NET

Copiare e salvare questo codice VB.NET nel file TestLib.vb:

Imports System
Imports System.Runtime.InteropServices

Public Class TestLib

  Const SimpLibName = "simplelib.dll"

   'Declare external functions using the DllImport attribute.
  <DllImport(SimpLibName, EntryPoint:="MySucc", _
             CallingConvention:=CallingConvention.StdCall)> _
             Public Shared Function Succ(ByVal AVal As Long) As Long
    End Function

  <DllImport(SimpLibName, EntryPoint:="MyPred", _
             CallingConvention:=CallingConvention.StdCall)> _
             Public Shared Function Pred(ByVal AVal As Long) As Long
    End Function

  Public Shared Sub Main()
  
    Dim TestVal As Long

    Try
      TestVal = 123
      Console.WriteLine("Value is " & TestVal)
      Console.WriteLine("Successor is " & Succ(TestVal))
      Console.WriteLine("Predecessor is " & Pred(TestVal))
    Catch e As Exception
      Console.WriteLine(e)
    End Try

  End Sub  'Main

End Class  'TestLib

Se .NET framework è installato in Windows, si può compilare il codice così:

 [pathto]vbc TestLib.vb

dove [pathto] è il percorso di .NET framework (example: c:\windows\microsoft.net\framework\v1.1.4322\ with .NET 1.1). Verrà creato il file TestLib.exe.

Se Mono è installato, si può anche provare a compilare il codice così:

 vbnc TestLib.vb

Si può anche provare a compilare la versione C#:

Una semplice app C#

Questo è l'equivalente codice per C#. Copiarlo e salvarlo nel file TestLib.cs.

using System;
using System.Runtime.InteropServices;

public class TestLib {
  
  const string SimpLibName = "simplelib.dll";

   //Declare external functions using the DllImport attribute.
  [DllImport(SimpLibName, EntryPoint="MySucc",
             CallingConvention=CallingConvention.StdCall)]
             public static extern long Succ(long AVal);

  [DllImport(SimpLibName, EntryPoint="MyPred", 
             CallingConvention=CallingConvention.StdCall)] 
             public static extern long Pred(long AVal);

  public static void Main()
  {
    long TestVal;

    try
    {
      TestVal = 123;
      Console.WriteLine("Value is " + TestVal);
      Console.WriteLine("Successor is " + Succ(TestVal));
      Console.WriteLine("Predecessor is " + Pred(TestVal));
    }
    catch(Exception e)
    {
      Console.WriteLine(e);
    }
  }
}

Con .NET, si può compilarlo così:

 [pathto]csc TestLib.cs

Con Mono, si può compilarlo così:

 mcs TestLib.cs

Con .NET e Mono, la compilazione creerà il file TestLib.exe.

Una semplice app Pascal utilizzando Oxygene

Copiare e salvare il seguente codice Pascal nel file TestLib.pas:

namespace TestLib;

interface

uses
  System.Runtime.InteropServices;
  
const
  SimpleLibName = 'simplelib.dll';

type
  TestLib = class
  private
    [DllImportAttribute(SimpleLibName, EntryPoint:='MySucc',
                        CallingConvention:=CallingConvention.StdCall)]
    class method Succ(AVal : Int64) : Int64; external;  

    [DllImportAttribute(SimpleLibName, EntryPoint:='MyPred',
                        CallingConvention:=CallingConvention.StdCall)]
    class method Pred(AVal : Int64) : Int64; external;  
  public
    class method Main;
  end;
    
implementation

class method TestLib.Main;
var
  TestVal : Int64;
begin
  try
    TestVal := 123;
    Console.WriteLine('Value is ' + TestVal);
    Console.WriteLine('Successor is ' + Succ(TestVal));
    Console.WriteLine('Predecessor is ' + Pred(TestVal));
  except
    on E: Exception do
      Console.WriteLine(E.Message);
  end;
end;

end.

Il compilatore free Oxygene Object Pascal è disponbile qui RemObjects Software.

Con .NET e Mono, si può compilare TestLib.pas così:

 [pathto]oxygene TestLib.pas

Con .NET e Mono, verrà creato il file testlib.exe.

Eseguire la semplice app

Con .NET, eseguire la app compilata così:

 testlib

Se .NET trova simplelib.dll, l'output nella console sarà:

 Value is 123
 Successor is 124
 Predecessor is 122

Con Mono, eseguire la app compilata così:

 mono TestLib.exe

Mono cercherà anche il file simplelib.dll -- e questo è il motivo per cui è stata rinominata la libreria compilata in Linux e macOS.

Notare che i files ".exe" di .NET/Mono non contengono codice compilato nativo. Invece, contengono bytecode eseguito da .NET/Mono a runtime. Come risultato, si può prendere un file .NET .exe creato in Windows ed eseguirlo con Mono su macOS e Linux (e viceversa) senza ricompilarlo. Si dovrà ricompilare le librerie Pascal su ogni piattforma che si vuole supportare.

Quando usare librerie native con .NET/Mono

Perché non scrivere semplicemente tutto il codice in VB.NET o C#? Ci sono diverse situazioni in cui questa può non essere una buona idea:

  • quando si ha un lungo o complesso codice Pascal che non si vuole riscrivere (e ricorreggere) in C#;
  • quando si hanno librerie native che devono essere utilizzate da apps sia native, sia .NET/Mono;
  • quando ci sono motivi di prestazioni (presumilmente codice compilato in FPC o Delphi è più veloce di quello equivalente compilato sotto .NET/Mono);
  • quando è necessario un accesso a basso livello al sistema operativo, non facilmente disponibile con .NET/Mono;
  • quando è necessario sviluppare codice velocemente in un linguaggio che you're more proficient in for a multi-developer .NET/Mono project.

Appunti Mono

1. Poiché Visual Basic è un perfetto sconosciuto a Linux e macOS, probabilmente si vorrà sviluppare apps .NET e Mono utilizzando C#, che è simile a C++ (e Object Pascal). O usare il compilatore Oxygene e sviluppare apps .NET e Mono con un Object Pascal familiare.

2. Mono in macOS comprende uno script per la disinstallazione. E' bene eseguire questo script prima di installare una nuova versione di Mono:

  • In Finder, navigare fino a /Library/Receipts.
  • Ctrl+click su MonoFramework.pkg e scegliere Show Package Contents dal menu popup.
  • Doppio-click su Contents folder.
  • Doppio-click su Resources folder.
  • Trascinare una copia di uninstallMono.sh sul desktop.
  • Aprire una finestra Terminal.
  • cd desktop
  • sudo ./uninstallMono.sh e inserire la password.

3. In generale, non utilizzare units Lazarus nelle librerie. Le librerie generalmente non hanno una interfaccia utente. Confine your use to Free Pascal units like System, SysUtils, StrUtils, DateUtils, Classes, Variants and Math.

4. Se si ha bisogno di una interfaccia utente per operare con le librerie, si programmi come un'applicazione Windows Forms. Si riporta di seguito un semplice esempio di form. Copiare e salvare questo codice nel file MyForm.cs.

using System;
using System.Windows.Forms;

public class MyForm: Form
{
  public MyForm ()
  {
    this.Text = "A .NET/Mono Windows Forms App";
    this.Width = 400;

    Button b = new Button();
    b.Left = 15;
    b.Top = 20;
    b.Width = this.Width-30;
    b.Height = 30;
    b.Text = "Click Me";
    b.Click += new EventHandler(button_Click);
    this.Controls.Add(b);
  }
  void button_Click(object sender, EventArgs e)
  {
    MessageBox.Show("Hello");
  }
}

public class MyApp
{
  public static void Main()
  {
    MyForm aForm = new MyForm();
    Application.Run(aForm);
  }
}

Compilare questo codice con Mono così:

 mcs -r:System.Windows.Forms MyForm.cs

Run the app as follows:

 mono MyForm.exe

In macOS, si può anche creare una normale app bundle utilizzando l'utility macpack:

 macpack -n MyForm -m winforms MyForm.exe

che crea MyForm.app bundle, che può essere double-clicked, dropped onto the Dock, etc.

5. Su Linux e macOS, Mono ora comprende MonoDevelop, una semplice IDE per l'editing e la compilazione del codice.

6. If you have any questions or comments about using Pascal libraries with .NET or Mono, please post them to the Lazarus forum.