16. Calling XLPack functions from other programming languages

Introduction

C/C++ program can call numerical calculation function modules of XLPack (or XLPack Lite) through XLPack API. Other programming languages can also be used if those languages are capable of calling external C programs.

Please refer to the sample programs for major programming languages (C#, F#, VB.NET, Python and Delphi(Pascal)) included in the XLPack SDK. The common technical points are described and simple example programs of those languages are shown below.

Library modules

To use numerical calculation functions of XLPack, it is necessary to call an appropriate library module with valid interface. The appropriate library module must be chosen as listed below.

Function to be calledOSBit versionLibrary module to be used
XLPack module 1 functionsWindows64 bitXLPack1.dll
XLPack module 2 functionsWindows64 bitXLPack2.dll
XLPack module 3 functionsWindows64 bitXLPack3.dll
XLPack module 4 functionsWindows64 bitXLPack4.dll
XLPack module 1 to 4 common functionsWindows64 bitXLPack0.dll
XLPack Lite functionsWindows64 bitXLPackLite.dll
XLPack module 1 functionsWindows32 bitXLPack1_32.dll
XLPack module 2 functionsWindows32 bitXLPack2_32.dll
XLPack module 3 functionsWindows32 bitXLPack3_32.dll
XLPack module 4 functionsWindows32 bitXLPack4_32.dll
XLPack module 1 to 4 common functionsWindows32 bitXLPack0_32.dll
XLPack Lite functionsWindows32 bitXLPackLite_32.dll
XLPack module 1 functionsmacOS64 bitXLPack1.dylib
XLPack module 2 functionsmacOS64 bitXLPack2.dylib
XLPack module 3 functionsmacOS64 bitXLPack3.dylib
XLPack module 4 functionsmacOS64 bitXLPack4.dylib
XLPack module 1 to 4 common functionsmacOS64 bitXLPack0.dylib
XLPack Lite functionsmacOS64 bitXLPackLite.dylib

The calling convention of library module must be cdecl. For an entry name and parameter definitions, please refer to the details of functions described in C interface function reference manual.

.NET languages (C#, F#, VB.NET)

Example: Solve the following system of linear equations.

  Ax = b
             ( 10  -7   0 )       ( 7 )
  where, A = ( -3   2   6 ),  b = ( 4 )
             (  5  -1   5 )       ( 6 )


C# example program is shown below.

using System;
using System.IO;
using static XLPack;

public class Test
{

static void Test_dgesv()
{
    double[] a = new double[9], b = new double[3];
    int[] ipiv = new int[3];
    int n, nrhs, lda, ldb, info;

    n = 3; nrhs = 1; lda = 3; ldb = 3;
    a[0] = 10.0; a[3] = -7.0; a[6] = 0.0;
    a[1] = -3.0; a[4] = 2.0; a[7] = 6.0;
    a[2] = 5.0; a[5] = -1.0; a[8] = 5.0;
    b[0] = 7.0; b[1] = 4.0; b[2] = 6.0;

    dgesv(n, nrhs, lda, a, ipiv, ldb, b, out info);
    Console.Write("info = {0}\n", info);
    Console.Write("x = {0}  {1}  {2}\n", b[0], b[1], b[2]);
}

public static int Main(string[] args)
{
    Test_dgesv();
    return 0;
}

}

The statement “using static XLPack” allows you to call XLPack functions.

The class XLPack contains all the necessary codes to interface to XLPack. In this class, the function interface is defines by specifying DLL file name, calling convention and entry name.

using System.Runtime.InteropServices;

public static class XLPack
{
    const string DLL1 = "XLPackLite.dll";

    [DllImport(DLL1, CallingConvention = CallingConvention.Cdecl)]
    public extern static void dgesv(int n, int nrhs, int lda, double[] a, int[] ipiv, int ldb, double[] b, out int info);

    . . .

}

Result.

info = 0
x = 0  -1  1

Although the syntax is different from C#, F# and VB.NET can call XLPack functions in a similar fashion. Example programs are shown below.

F# example program (“open XLPack.F” declares to use interface module).

open XLPack.F

module TestDgesv =

    let n = 3
    let nrhs = 1
    let lda = 3
    let a = [| 10.0; -3.0; 5.0; -7.0; 2.0; -1.0; 0.0; 6.0; 5.0 |]
    let ldb = 3
    let b = [| 7.0; 4.0; 6.0 |]
    let ipiv = Array.create n 0
    let mutable info = 0
    dgesv(n, nrhs, lda, a, ipiv, ldb, b, &info)
    printfn "info = %d" info
    printfn "x = %A" b

F# interface module.

namespace XLPack

module F =

    open System.Runtime.InteropServices

    [<Literal>]
    let Dll1 = "XLPackLite.dll"

    [<DllImport(Dll1, CallingConvention = CallingConvention.Cdecl, EntryPoint="dgesv")>]
    extern void dgesv(int n, int nrhs, int lda, double[] a, int[] ipiv, int ldb, double[] b, int& info)

    . . .

Result.

info = 0
x = [|0.0; -1.0; 1.0|]

VB.NET example program (“Imports XLPack” declares to use interface module).

Imports XLPack

Class Test

Shared Sub TestDgesv
	Dim A(8) As Double, LdA As Integer, B(2) As Double, LdB As Integer
	Dim IPiv(2) As Integer
	Dim N As Integer, Info As Integer

	N = 3: LdA = 3: LdB = 3
	A(0) = 10.0: A(3) = -7.0: A(6) = 0.0
	A(1) = -3.0: A(4) = 2.0: A(7) = 6.0
	A(2) = 5.0: A(5) = -1.0: A(8) = 5.0
	B(0) = 7.0: B(1) = 4.0: B(2) = 6.0

	Call Dgesv(N, LdA, A, IPiv, LdB, B, Info)
	Console.WriteLine("Info = {0}", Info)
	Console.WriteLine("X = {0}  {1}  {2}", B(0), B(1), B(2))
End Sub

Public Shared Sub Main(ByVal args() As String)
	Call TestDgesv
End Sub

End Class

VB.NET interface module.

Imports System.Runtime.InteropServices

Class XLPack

    Const DLL1 = "XLPackLite.dll"

    <DllImport(DLL1, CallingConvention:=CallingConvention.Cdecl, EntryPoint:="dgesv")>
    Private Shared Sub XL_dgesv(N As Integer, Nrhs As Integer, LdA As Integer, A() As Double, IPiv() As Integer, LdB As Integer, B() As Double, ByRef Info As Integer)
    End Sub

    Public Shared Sub Dgesv(N As Integer, LdA As Integer, A() As Double, IPiv() As Integer, LdB As Integer, B() As Double, ByRef Info As Integer, Optional Nrhs As Integer = 1)
        Call XL_dgesv(N, Nrhs, LdA, A, IPiv, LdB, B, Info)
    End Sub

    . . .

End Class

Result.

info = 0
x = 0  -1  1

Python

There are several ways to call C functions from Python, but here we will use ctypes. Matrices are defined by numpy.array.

The example program is shown below. The interface part is separated just like .NET language example programs above. The “from XLPack import *” statement declares to use the interface module.

import numpy as np
from XLPack import *

def TestDgesv():
    n = 3
    nrhs = 1
    a = np.array([
        [10.0, -3.0, 5.0],
        [-7.0, 2.0, -1.0],
        [0.0, 6.0, 5.0]])
    b = np.array([7.0, 4.0, 6.0])
    ipiv = np.empty(n)
    info = Dgesv(n, nrhs, a, ipiv, b)
    print(b, info)

# -----------------

TestDgesv()

The interface part is shown below.

from ctypes import *

dll1 = CDLL("XLPackLite.dll")

def Dgesv(n, nrhs, a, ipiv, b):
    dll1.dgesv.argtype = [c_int, c_int, c_int, POINTER(c_double), POINTER(c_int), c_int, POINTER(c_double),
        POINTER(c_int)]
    if a.ndim <= 1:
        lda = n
    else:
        lda = a.shape[1]
    ldb = b.shape[0]
    info = c_int()
    dll1.dgesv(c_int(n), c_int(nrhs), c_int(lda), a.ctypes.data_as(POINTER(c_double)),
        ipiv.ctypes.data_as(POINTER(c_int)), c_int(ldb), b.ctypes.data_as(POINTER(c_double)), byref(info))
    return info.value

. . . 

Result.

[ 0. -1.  1.] 0

Delphi (Pascal)

The example program of Delphi (Pascal) is shown below.

program test_xlpack;

uses XLPack;

procedure test_dgesv;
var
    a: array[1..9] of Double; b: array[1..3] of Double;
    n, nrhs, lda, ldb: Integer;
    ipiv: array[1..3] of Integer;
    info: Integer;
begin
    n := 3; nrhs := 1; lda := 3; ldb := 3;
    a[1] := 10.0; a[4] := -7.0; a[7] := 0.0;
    a[2] := -3.0; a[5] := 2.0; a[8] := 6.0;
    a[3] := 5.0; a[6] := -1.0; a[9] := 5.0;
    b[1] := 7.0; b[2] := 4.0; b[3] := 6.0;
    Dgesv(n, nrhs, lda, a, ipiv, ldb, b, info);
    Writeln('info = ', info);
    Writeln('x =');
    Writeln(b[1], '  ', b[2], '  ', b[3]);
end;

begin
    test_dgesv;
end.

The interface part is shown below.

unit XLPack;

interface

const
    dll1 = 'XLPackLite.dll';

procedure Dgesv(n, nrhs, lda: Integer; var a: array of Double; var ipiv: array of Integer; ldb: Integer;
    var b: array of Double; var info: Integer);

{****************}

implementation

procedure XL_Dgesv(n, nrhs, lda: Integer; var a: Double; var ipiv: Integer; ldb: Integer; var b: Double;
    var info: Integer); cdecl; external dll1 name 'dgesv';

procedure Dgesv(n, nrhs, lda: Integer; var a: array of Double; var ipiv: array of Integer; ldb: Integer;
    var b: array of Double; var info: Integer);
begin
    XL_Dgesv(n, nrhs, lda, a[0], ipiv[0], ldb, b[0], info);
end;

end.

実行結果

info = 0
x =
 0.00000000000000E+0000  -1.00000000000000E+0000   1.00000000000000E+0000
Top