質問

私の上司は、VB6(またはその後の他の言語)から呼び出すことができるボリュームシャドウコピーを実行できるC ++(MSVC ++ 2010)でDLLを書くことを望んでおり、完成していない間にステータスの更新を戻すことができます。彼はそれを「イベント」と呼んでいます。

私はついにcomを学ぶ必要があると感じています(私はむしろ...)...また、コールバック関数が頭に浮かぶのですが、VB6からC ++への関数ポインターを引き渡すことは確かに不可能です。

誰かが私が学ばなければならないことと、これをどのようにcomの有無にかかわらず、どのように達成できるかを概説できますか?

編集:質問に答えるには、ワークフローは次のとおりです。

  1. VB6アプリは、バックアップするファイルを決定します

  2. 私はパスを与えられ、このパスを含む一時的なボリュームシャドウコピーを作成し、マウントポイント(または同様)を返します

    • このステップの間に、私は定期的にVB6アプリに自分がどれだけ離れているかを伝えます

  3. VB6アプリはシャドウコピーのバックアップを作成し、シャドウコピーを削除します。

役に立ちましたか?

解決

ポインターをVBアプリからC ++ DLLアプリまでの「Display Progress」関数に渡すことができます。 AddressOf オペレーター:

Declare Function CallMyDll ...

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

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

それほど明白ではないいくつかのゴッチャ:

  1. を使用してC ++関数ポインターを宣言する必要があります __stdcall 電話会議. 。 (ありがとう、アレクサンドルC!)

  2. VBコールバック関数で、 パラメーターをバリューとして明示的にマークします キーワードを使用します ByVal. 。同様に、C ++関数ポインターでは、パラメーターをby-referenceとしてマークしないでください。

  3. 文字列をコールバックに渡すか、そこから文字列を取得する場合は、そのVBを考慮する必要があります StringSはcに等しくありません char*S、C ++ std::stringS、またはMicrosoft's CStrings。 VB StringSは、Microsoftのかなりあいまいなものにマッピングする必要があります BSTR データ・タイプ。

  4. 私は非常に重要なことを忘れていました:あなたのコールバックはVBモジュール内にある必要があります(つまり、それはクラスではなく「単なる関数」またはフォームの方法でなければなりません)。

他のヒント

上司は、DLLによってエクスポートされる関数を呼び出すことができます 宣言する 声明。それはうまくスケーリングしませんが、単純なAPIでは問題ありません。関数は、extern "c"および__declspec(dllexport)宣言者でエクスポートし、__stdcall呼び出しコンベンションを使用し、単純な引数タイプのみを使用する必要があります。

これらのステータスの更新を提供する必要があるのはいつですか?
VSSのセットアップ中?または、データなどをバックアップしている間?後者の場合、VSSはパスを返すだけで、VBから直接使用できます。
しかし、セットアップの場合...それも理にかなっているかもしれませんが、それはかなり遅いかもしれませんが、それを状態マシンに変えることができると思います - すべてのVSS API呼び出しを大きなスイッチ()に入れて、呼び出す関数を作成しますそれらを1つずつ、状態varを更新します。

更新:私はこのようなものを意味します。 init()およびstep()は、dllによってエクスポートされ、VBから呼び出されます。
または、スレッドをスポーンして、Step()でスリープ(100)のようにステータスの更新をすべて実行し、ステータスの更新を返すことができます。

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

私はcomなしで仕事をします。代わりに、VBパーツにDLLにウィンドウハンドルを送信すると、DLLはその進行状況を示すメッセージをウィンドウに投稿します。

COMを使用できますが、それはスレッジハンマーでハエをスワッティングする範囲のようなものです。

Unix-yルートを取ります。コピーを実行し、進行状況インジケーターをSTDアウトに出力するプログラムを作成します。 VBアプリをこの出力を解析して、完了率をつかみます。

私はこれをします:

  • VBアプリは、DLLの関数を呼び出して、シャドウコピーの起動を求めます。 DLLはシャドウコピーを実行し、ID(スレッドID?)をVBアプリに戻すスレッドを起動します

  • VBアプリは、以前に受信した操作IDを渡すDLLの関数「進行状況」を定期的に呼び出します。

  • これにより、VBアプリはいくつかの操作を並行して起動できます。

コピーを実行するスレッドは、時々「進行状況」変数を更新する必要があります。コピーを停止するDLLの別の機能も役立ちます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top