Question

Mon patron me veut écrire une DLL en C ++ (MSVC ++ 2010) qui peut effectuer un cliché instantané des volumes qu'il peut appeler à partir VB6 (ou ultérieurement d'autres langues) et qui peut donner des mises à jour de statut dos alors qu'il est pas fini. Il l'appelle "événements".

J'ai le sentiment que je dois enfin apprendre COM (je préfère ne pas ...) ... aussi, une fonction de rappel vient à l'esprit, mais il est certainement impossible de main sur des pointeurs de fonction de VB6 à C ++ ?

Quelqu'un peut-il décrire ce que je dois apprendre et comment cela peut être accompli, avec ou sans COM?

EDIT: pour répondre à une question, le flux de travail est censé être:

  1. app VB6 détermine les fichiers à sauvegarder

  2. Je donne un chemin et faire une copie d'ombre de volume temporaire qui comprend ce chemin et redonner un point de montage (ou similaire)

    • au cours de cette étape, je dis régulièrement l'application VB6 jusqu'où je suis

  3. application VB6 permet la sauvegarde de la copie d'ombre et puis supprime la copie d'ombre.

Était-ce utile?

La solution

Vous pouvez passer un pointeur à votre fonction « affichage de progression » de l'application VB à l'application DLL C ++ en utilisant l'opérateur AddressOf:

Declare Function CallMyDll ...

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

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

Quelques pas si évidentes gotchas:

  1. Vous devez déclarer votre pointeur de fonction C ++ en utilisant le __stdcall convention d'appel . (Merci, Alexandre C!)

  2. Dans votre fonction de rappel VB, marquer explicitement vos paramètres comme par valeur utilisant le mot-clé ByVal. De même, dans votre C ++ pointeur de fonction, ne marquez pas vos paramètres comme par référence.

  3. Si vous voulez passer une chaîne à la fonction de rappel, ou récupérer une chaîne à partir, vous devez prendre en considération le fait que VB Strings ne sont pas égaux à C char*s, C ++ std::strings, ou les CStrings de Microsoft. VB Strings doivent être mis en correspondance avec le type de données BSTR plutôt obscure de Microsoft.

  4. J'ai oublié une chose très importante. Votre rappel doit être à l'intérieur d'un module VB (à savoir, il doit être « simple fonction », pas une classe ou la méthode d'un formulaire)

Autres conseils

Votre patron peut appeler des fonctions exportées par une DLL avec Declare déclaration. Cela n'évolue pas bien mais est très bien pour une API simple. Votre fonction doit être exportée avec le extern « C » et déclarateurs __declspec (dllexport) de, utilisez la convention d'appel __stdcall et utiliser uniquement les types d'arguments simples.

Quand il doit fournir ces mises à jour le statut
Lors de la configuration VSS? Ou lors de la sauvegarde des données et tel? Dans ce dernier cas VSS retourne juste un chemin, qui peut être utilisé directement à partir de VB.
Mais pour l'installation ... il pourrait faire trop de sens, car il peut être assez lent, mais je suppose que vous pouvez le transformer en une machine d'état - mettre tous les appels API VSS dans un grand interrupteur () et faire une fonction qui les appeler un par un et mettre à jour le var état.

Mise à jour: Je veux dire quelque chose comme ça. Init () et l'étape () sont vos fonctions exportées par votre dll et appelé de VB.
Vous pouvez frayer un fil pour faire tout ce que (toujours dans le dll) et retour les mises à jour d'état après comme sommeil (100) à l'étape ().

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

Je faire le travail sans COM. Au lieu de cela, j'aurais la partie VB envoyer une poignée de fenêtre à la DLL et la DLL affichera un message à la fenêtre indiquant ses progrès.

Vous pouvez utiliser COM, mais est un peu dans la gamme de swatting une mouche avec un marteau de forgeron.

Prendre la route unix-y. Créer un programme qui exécute la copie et délivre un indicateur de progression à std sur. Faire l'application VB parse cette sortie pour saisir le pourcentage d'achèvement.

Je ferais ceci:

  • l'application VB appelle la fonction dans votre DLL demandant de commencer la copie d'ombre. Votre dll démarre un thread qui exécute la copie d'ombre et retourne un ID (un identifiant de fil?) Retour à l'application VB

  • L'application VB appelle périodiquement une fonction "Progress" dans votre DLL passer l'ID opération reçue avant: la fonction retourne un nombre entier de progression 0-100 pour indiquer l'état d'avancement

  • De cette façon, l'application VB peut lancer plusieurs opérations en parallèle.

Le fil qui effectue la copie doit mettre à jour une variable « progrès » de temps en temps. Une autre fonction dans la DLL qui arrête la copie serait utile aussi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top