2014-12-18 7 views
5

Ho uno script Inno Setup in esecuzione, in cui utilizzo innocallback.dll da Sherlock Software.Chiama DLL C# da Inno Setup con callback

Questa DLL esegue il wrapping di una mia procedura in modo che possa essere passata a una DLL C#.

Non voglio usare questa DLL, voglio chiamare direttamente il mio metodo C# esportato e passare ad esso la procedura di callback.

La mia domanda è:

Come posso passare la mia procedura Inno Setup (@mycallback) al mio C# DLL in modo che posso usarlo come mio delegate/UnmanagedFunctionPointer?

Come ho detto, questo codice funziona, ma voglio utilizzare il minor numero possibile di DLL esterne.

Ecco il mio codice:

Inno Setup script

type 
    TTimerProc=procedure(); 
    TProgressCallback=procedure(progress:Integer); 
    
function WrapProgressProc(callback:TProgressCallback; paramcount:integer):longword; 
    external '[email protected]:innocallback.dll stdcall'; 

function Test(callback:longword): String; 
    external '[email protected]:ExposeTestLibrary.dll stdcall'; 

var 
    endProgram : Boolean; 

procedure mycallback(progress:Integer); 
begin 
    MsgBox(IntToStr(progress), mbInformation, MB_OK);  
    if progress > 15 then 
    begin 
    endProgram := True; 
    end 
end; 
   
function InitializeSetup:boolean; 
var 
    progCallBack   : longword; 
    callback       : longword; 
    msg            : longword; 
    msg2           : widestring; 
begin 
    endProgram := False; 
    progCallBack:= WrapProgressProc(@mycallback,1); //Our proc has 1 arguments 
    Test(progCallBack); 
    result:=true; 
end; 

E questo è il mio codice C#

public class TestClass 
{ 
    [UnmanagedFunctionPointer(CallingConvention.StdCall)] 
    public delegate void ReportProgress(uint progress); 

    public static ReportProgress m_reportProgess; 
    static uint m_iProgress; 
     
    [DllExport("Test", CallingConvention = CallingConvention.StdCall)] 
    static int Test(ReportProgress rProg) 
    { 
        m_iProgress = 0; 
        m_reportProgess = rProg; 
        System.Timers.Timer pTimer = new System.Timers.Timer(); 
        pTimer.Elapsed += aTimer_Elapsed; 
        pTimer.Interval = 1000; 
        pTimer.Enabled = true; 
        GC.KeepAlive(pTimer); 
        return 0; 
    } 

    static void aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
        m_iProgress++; 
        m_reportProgess(m_iProgress); 
    } 
} 

risposta

2

Non c'è modo di abbandonare l'uso della confezione Libreria InnoCallback poiché non è possibile definire una procedura di callback con una convenzione di chiamata di tua scelta in Inno Setup, né puoi definire un callback con la convenzione di chiamata register (quella specifica del compilatore Delphi) nella tua libreria C#.

A causa di questo limite è necessario utilizzare una libreria esterna, che avvolge un metodo di richiamata da Inno Setup in una funzione con una convenzione di chiamata che la libreria può utilizzare (InnoCallback utilizza stdcall per quello).

Quindi, ciò che si richiede sarebbe possibile se si stesse scrivendo la libreria in una lingua che supporta la convenzione di chiamata register di Delphi. Per curiosità, in Delphi è possibile scrivere ad esempio:

library MyLib; 

type 
    TMyCallback = procedure(IntParam: Integer; StrParam: WideString) of object; 

procedure CallMeBack(Callback: TMyCallback); stdcall; 
begin 
    Callback(123, 'Hello!'); 
end; 

exports 
    CallMeBack; 

begin 
end. 

E in Inno Setup poi (senza librerie involucro):

[Setup] 
AppName=My Program 
AppVersion=1.5 
DefaultDirName={pf}\My Program 

[Files] 
Source: "MyLib.dll"; Flags: dontcopy 
[Code] 
type 
    TMyCallback = procedure(IntParam: Integer; StrParam: WideString); 

procedure CallMeBack(Callback: TMyCallback); 
    external '[email protected]:mylib.dll stdcall'; 

procedure MyCallback(IntParam: Integer; StrParam: WideString); 
begin 
    MsgBox(Format('IntParam: %d; StrParam: %s', [IntParam, StrParam]), 
    mbInformation, MB_OK); 
end; 

procedure InitializeWizard; 
begin 
    CallMeBack(@MyCallback); 
end; 
+1

Ho appena visto che hai il distintivo d'oro inno-setup . Complimenti :) – Bongo