Pregunta

Mi jefe quiere que escriba una DLL en C ++ (MSVC ++ 2010) que puede realizar una copia de sombra de volumen que puede llamar desde VB6 (o en un punto posterior en otros idiomas) y que puede devolver las actualizaciones de estado mientras no está terminado . Lo llama "eventos".

Tengo la sensación de que finalmente necesito aprender com (prefiero no ...) ... Además, ¿me viene a la mente una función de devolución de llamada, pero es seguramente imposible entregar los punteros de la función de VB6 a C ++?

¿Alguien puede describir lo que tengo que aprender y cómo se puede lograr esto, con o sin com?

Editar: Para responder una pregunta, se supone que el flujo de trabajo es:

  1. La aplicación VB6 determina qué archivos copiar

  2. Me dan una ruta y hago una copia de sombra de volumen temporal que incluye esta ruta y devuelve un punto de montaje (o similar)

    • Durante este paso, regularmente le digo a la aplicación VB6 qué tan lejos estoy

  3. La aplicación VB6 realiza la copia de seguridad de la copia de la sombra y luego elimina la copia de la sombra.

¿Fue útil?

Solución

Puede pasar un puntero a su función "Mostrar progreso" desde la aplicación VB a la aplicación DLL C ++ usando la AddressOf operador:

Declare Function CallMyDll ...

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

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

Algunos no tan obvios Gotchas:

  1. Tienes que declarar el puntero de su función C ++ usando el __stdcall Convención de llamadas. (Gracias, Alexandre C!)

  2. En su función de devolución de llamada VB, Marque explícitamente sus parámetros como valor Usando la palabra clave ByVal. Del mismo modo, en el puntero de su función C ++, no marque sus parámetros como referencia.

  3. Si desea pasar una cadena a la devolución de llamada o recuperar una cadena de ella, debe tener en cuenta que VB Strings no son iguales a C char*S, C ++ std::stringS, o Microsoft's CStrings. VB StringS debe mapearse a la oscuridad de Microsoft BSTR tipo de datos.

  4. Olvidé algo muy importante: su devolución de llamada debe estar dentro de un módulo VB (es decir, tiene que ser una "mera función", no una clase o un método de forma).

Otros consejos

Su jefe puede llamar a las funciones exportadas por un DLL con el Declarar declaración. Eso no escala bien, pero está bien para una API simple. Su función debe exportarse con los declaradores externos "C" y __Declspec (DLEXPORT), usar la convención de llamadas __STDCALL y usar solo tipos de argumentos simples.

¿Cuándo tiene que proporcionar estas actualizaciones de estado?
Mientras se configuran VSS? ¿O mientras retrocede los datos y tal? En el último caso, VSS solo devuelve una ruta, que se puede usar directamente desde VB.
Pero para la configuración ... también puede tener sentido, porque puede ser bastante lento, pero supongo que puede convertirlo en una máquina de estado: coloque todas las llamadas de API VSS en un interruptor grande () y realizar una función que llame ellos uno por uno y actualizar el estado var.

Actualización: me refiero a algo como esto. Init () y step () son sus funciones exportadas por su DLL y llamadas desde VB.
Alternativamente, puede generar un hilo para hacer todo eso (aún en la DLL) y devolver actualizaciones de estado después de que me gusta el sueño (100) en step ().

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);
}

Haría el trabajo sin com. En cambio, haría que la parte VB envíe un mango de ventana a la DLL, y la DLL publicará un mensaje en la ventana que dice su progreso.

Podrías usar com, pero eso está en el rango de golpear una mosca con un mazo.

Tome la ruta Unix-y. Cree un programa que realice la copia y emite un indicador de progreso para salir de la salida. Haga que la aplicación VB analice esta salida para obtener el porcentaje de finalización.

Yo haría esto:

  • La aplicación VB llama a la función en su DLL pidiendo que inicie la copia de la sombra. Su DLL inicia un hilo que realiza la copia de la sombra y devuelve una ID (¿un ID de hilo?) Volver a la aplicación VB

  • La aplicación VB llama periódicamente una función "progreso" en su DLL que pasa la ID de operación recibida antes: la función de progreso devuelve un entero 0-100 para indicar el progreso

  • De esta manera, la aplicación VB puede iniciar varias operaciones en paralelo.

El hilo que realiza la copia debe actualizar una variable de "progreso" de vez en cuando. Otra función en la DLL que detiene la copia también sería útil.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top