Domanda

Il mio capo mi vuole scrivere una DLL in C ++ (MSVC ++ 2010) in grado di eseguire un Volume Shadow Copy, che si può chiamare da VB6 (o in un momento successivo le altre lingue) e che può dare gli aggiornamenti di stato indietro mentre non è finito. Lui lo chiama "eventi".

Ho la sensazione che alla fine ho bisogno di imparare COM (Preferirei di no ...) ... Inoltre, una funzione di callback viene in mente, ma è sicuramente impossibile consegnare puntatori a funzione da VB6 a C ++ ?

Qualcuno può indicare quali devo imparare e come questo può essere realizzato, con o senza COM?

EDIT: per rispondere a una domanda, il flusso di lavoro dovrebbe essere:

  1. Determina VB6 app quali file per il backup

  2. Io sono dato un percorso e fare una copia shadow del volume temporanea che include questa strada e restituire un punto (o simile) mount

    • durante questa fase, dico regolarmente l'applicazione VB6 quanto lontano mi

      ??

  3. VB6 app rende il backup di copia shadow e quindi elimina copia shadow.

È stato utile?

Soluzione

È possibile passare un puntatore alla funzione "progresso di visualizzazione" dal VB app al app C ++ DLL utilizzando l'operatore AddressOf:

Declare Function CallMyDll ...

Sub DisplayStatus(ByVal SomeParameter As Long)
    ' ...
End SUb

Sub DoSomething()
    Call CallMyDll(AddressOf DisplayStatus)
End Sub

alcuni grattacapi non così ovvio:

  1. Si deve dichiarare il vostro puntatore a funzione C ++ utilizzando il __stdcall convenzione di chiamata . (Grazie, Alexandre C!)

  2. Nella funzione di callback VB, contrassegnare esplicitamente i parametri come per valore utilizzando la parola chiave ByVal. Allo stesso modo, nel vostro C ++ puntatore a funzione, non contrassegnare i parametri per riferimento.

  3. Se si vuole passare una stringa al callback, o recuperare una stringa da esso, si deve prendere in considerazione che Strings VB non sono uguale a C char*s, std::strings C ++, o CStrings di Microsoft. Strings VB devono essere mappati per tipo di dati BSTR piuttosto oscuro di Microsoft.

  4. Ho dimenticato una cosa molto importante:. Il vostro richiamata deve essere all'interno di un modulo VB (vale a dire, deve essere un "semplice funzione", non è una classe o un metodo di un modulo)

Altri suggerimenti

Il tuo capo può richiamare le funzioni esportate da una DLL con il Declare dichiarazione. Che non scala bene ma va bene per una semplice API. La funzione deve essere esportato con l'extern "C" e dichiaratori (dllexport) __declspec, utilizzare la convenzione di chiamata __stdcall e utilizzare solo semplici tipi di argomenti.

Quando si deve fornire questi aggiornamenti di stato?
Durante l'impostazione VSS? O mentre il backup dei dati e quali? Nel caso VSS quest'ultimo solo restituisce un percorso, che può essere usato direttamente da VB.
Ma per la configurazione ... potrebbe avere senso anche, perché può essere piuttosto lento, ma credo che si può trasformarlo in una macchina a stati - mettere tutte le chiamate API VSS in un grande interruttore () e portare una funzione che richiederebbero uno per uno e aggiornare lo stato di var.

Aggiornamento: Voglio dire qualcosa di simile. Init () e Step () sono le tue funzioni esportate dalla DLL e chiamato da VB.
In alternativa, è possibile generare un thread per fare tutto ciò che (ancora nel dll) e il ritorno aggiornamenti di stato dopo piace Sleep (100) al punto ().

int s; // state

int Init( void ) { s=0; }

int Step( void ) {

  switch( s ) {

    default: break;

    case 0: 
    CoInitialize(0); break;

    case 1: 
    r = CreateVssBackupComponents(&vssc); 
    if( FAILED(r) ) s=-1;
    if( vssc==0 ) s=-2;
    break;

    case 2: 
    r = vssc->InitializeForBackup();
    if( FAILED(r) ) s=-3; 
    break;

    case 3: 
    r = vssc->SetBackupState( FALSE, FALSE, VSS_BT_COPY, FALSE );
    if( FAILED(r) ) s=-4;
    break;

    [...]

  }

  s += (s>=0);
}

Vorrei fare il lavoro senza COM. Invece, mi piacerebbe avere la parte VB inviare un handle di finestra per la DLL e la DLL invierò un messaggio alla finestra dicendo il suo progresso.

Si potrebbe usare COM, ma questo è tipo di nella gamma di schiacciare una mosca con una mazza.

Prendere la strada unix-y. Creare un programma che esegue la copia e le uscite di un indicatore di avanzamento a std out. Rendere l'applicazione VB parse questa uscita per afferrare la percentuale di completamento.

Vorrei fare questo:

  • l'applicazione VB chiama la funzione nella DLL chiede di avviare la copia shadow. La DLL avvia un thread che esegue la copia shadow e restituisce un ID (un ID di thread?) Di nuovo alla VB app

  • L'applicazione VB chiama periodicamente una funzione di "Progress" nella DLL passando l'ID di funzionamento ricevuto prima: la funzione restituisce un intero corso 0-100 per indicare lo stato di avanzamento

  • In questo modo l'applicazione VB può lanciare diverse operazioni in parallelo.

Il thread che esegue la copia deve aggiornare una variabile "progresso" ogni tanto. Un'altra funzione nella DLL che interrompe la copia sarebbe utile anche.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top