2

C ++コード:

  typedef struct {
    int bd_number;                      // number of boardset
    int bd_copies;                      // how many copies
    int bd_reserve;                     // only allocate if needed
} bd_t,*bd_p;

typedef struct boardset_info {
    int     bs_copies;          
    int     bs_demand;          
    int     bs_allocated;       
    int     bs_ontable_avail;       
    int     bs_ontable_needed;      
    pstatus bs_status;              
    int     bs_played_sofar;        
} bsi_t, *bsi_p;

FC_ERRORCODE dropin_boards(bd_p boards) {
    int bs;

    bs_info = (bsi_p) calloc(total_boardsets+1, sizeof(bsi_t));//total_boardsets=8
    for (bs = 1; bs <= total_boardsets; bs++)
        bs_info[bs].bs_status = PS_OUTPLAY;

    while (boards->bd_number) { //boards-<bd_number is betweeen 1 and 8
        if (boards->bd_number < 0 || boards->bd_number > total_boardsets)
        {
            debprint("***Error dropin_boards***\n");
            debprint("boardsetnumber=%d\n",boards->bd_number);
            return FC_ERR_PARAM;
        }
        //code does not reach this point
    }

発信コード:

<StructLayout(LayoutKind.Sequential)>
Public Structure Flex_BoardSetInfo
    Public SetNumber As Integer
    Public Copies As Integer
    Public IsReserve As Integer
End Structure

<DllImport("FlexCalc2.dll", CallingConvention:=CallingConvention.StdCall)>
    Public Shared Function FlexCalcBoards(ByRef boards() As Flex_BoardSetInfo) As Flex_ErrorCode
    End Function

Dim boardsets() = GetBoardSetInfo() // creates an arry of 8 BoardsetInfo Elements

_result = FlexCalcWrapper.FlexCalcBoards(boardsets) 

デバッグファイルの最後の行には、bd_p-> board_number=517237496が記録されています。ボード番号は1から8に初期化されており、コードがC ++ dllに渡される前に、それが正しく行われていることを確認できます。どうすればこれを解決できますか?

編集:VB6から、このC++メソッドを機能させるためにハックを使用しました。

Declare Function FlexCalcBoards Lib "FlexCalc2.dll" (firstBoard As BoardsetInfo)
ret=FlexCalcBoards(Boards(0))

したがって、配列自体ではなく、配列の最初の要素を渡しました。(Un?)幸いなことに、ネットはこのトリックに当てはまりません...

4

2 に答える 2

2

ByRefをByValに置き換えます。配列はすでにポインタとしてマーシャリングされています。

ByRefを使用するbd_t**と、C側のaとのみ一致します。

于 2012-04-27T14:36:13.167 に答える
0

まあ、答えとコメントは何も悪いことではないことを示しているようだったので....
私は3つのことを見つけました:

1。ソリューション全体を再構築し、新しいFlexCalc2.dllをコピーしてテストプロジェクトに貼り付けた後でも、 Binフォルダにあったdllは置き換えられませんでした。

2.私はC++の初心者ですが、メソッドが配列へのポインターのみを受け取った場合、LBoundからUBoundを使用して配列を反復処理できないようです。示されている方法は、ある種のを実装するために気の利いた方法を使用していますが、ここでは非常に高い数(メモリアドレス?)を返すfor eachため機能しませんが、bd_p->boardnumberbd_p[index].boardnumber1〜8の範囲内の正しい数値を返します。配列の長さを追加のパラメーターとして関数に送信するだけで、すべて設定されました。(私が気にするすべての人にとっては貧乏人の選択と呼んでください;-))

3. Hans Passantは、C ++のメソッドシグネチャがtheReturnValue theMethod(theStruct * theArray)Netからのメソッドシグネチャである場合、配列を渡す必要があると述べていましたByVal(VB6では、これは構文エラーを生成しますが、そうではありません)可能)。*配列へのポインタが渡されたという事実は、構造体のですでに宣言されているため、すぐにはわかりませんtypedef

于 2012-04-27T19:01:41.877 に答える