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! boardnumbers 初始化为 1 到 8,我可以在代码传递给 C++ dll 之前检查是否已正确完成。我该如何解决这个问题?

编辑:从 VB6 开始,我们使用 hack 来让这个 C++ 方法工作:

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

所以,我们传递了数组的第一个元素而不是数组本身!(不?)幸运的是,Net 并没有中招……

4

2 回答 2

2

将 ByRef 替换为 ByVal。数组已经被编组为指针。

使用 ByRef 只会匹配bd_t**C 端的 a 。

于 2012-04-27T14:36:13.167 回答
0

好吧,答案和评论似乎表明应该没有错,所以....
我发现了三件事:

1. 即使在重建整个解决方案并将新的 FlexCalc2.dll 复制并粘贴到 testproject 之后,旧的副本驻留在 Bin 文件夹中的 dll 未被替换。

2. 我是 C++ 的新手,但是当方法只接收到指向它的指针时,似乎无法使用 LBound 到 UBound 遍历数组。显示的方法使用一种漂亮的方式来实现一种for each,但在这里它不起作用,因为bd_p->boardnumber返回一个非常高的数字(内存地址?),但是bd_p[index].boardnumber返回 1-8 范围内的正确数字。我只是将数组的长度作为一个额外的参数发送给函数,然后我就准备好了。(尽管我在乎,称它为穷人的选择;-))

3. Hans Passant 说得对,当 C++ 中的方法签名是theReturnValue theMethod(theStruct * theArray)来自 Net 的方法签名时,您必须传递数组ByVal(在 VB6 中,这会产生语法错误,而不是可能的)。传递了指向数组的指针这一事实并不立即显而易见,因为*已经在typedef结构的 中声明了。

于 2012-04-27T19:01:41.877 回答