0

首先,我要说我已经到处寻找答案,当我找到一些东西时,这对我来说都是胡言乱语,而不是 C++ 程序员。编程对我来说只是一种爱好。

我在 C# winforms 项目中使用 Visual Studio 2010 Ultimate,以防万一!

问题是我正在尝试使用来自非托管 DLL 的函数(Bo Haglund's Double Dummy Solver)。他的自述文件没有多大帮助,关于如何使用他的 DLL 的文章令人惊讶地少(即没有)。

我有我希望使用的 DLL 中函数的原型。

extern "C" __declspec(dllimport) int __stdcall CalcDDtablePBN(struct ddTableDealPBN tableDealPBN, struct ddTableResults * tablep);

我对指针不太了解,但我猜我会在 C# 中使用“ref”。

这是他关于该功能的自述文件:

计算表

CalcDDtable 计算所有 20 个王牌花色/庄家牌组合的初始 52 张牌的双倍虚拟值。

在调用 CalcDDtable 之前,必须声明“ddTableResults”类型的结构。CalcDDtable 返回一个状态整数,“无故障”表示 DLL 在“ddTableResults”类型结构中提供双重虚拟分数。状态码:
1=无故障,其他状态码为错误,代码与 SolveBoard 状态码相同。

结构“ddTableDeal”定义了要分析的发牌。结构 ddTableDeal { 无符号整数卡[4][4]; /* 第一个索引是手,第二个索引是花色,与 SolveBoard 的 deal.remainCards 的编码相同。*/ };

struct ddTableResults { /* For each combination trump suit / declarer hand, the DLL provides the double dummy score. */
  int resTable[5][4];   /* 1st index is trump (0=Spades, 1=Hearts, 2=Diamonds, 3=Clubs, 4=No Trump 2nd index is declarer hand, 0=North, 1=East, 2=South, 3=West */
};

CalcDDtablePBN

在 CalcDDtablePBN 中,交易信息中的剩余卡片以 PBN 文本格式给出,请参阅上述 SolveBoardPBN 的描述。否则,CalcDDtablePBN 与 CalcDDtable 相同。

struct ddTableDealPBN {
  char cards[80];
};

我导入的函数如下:

[DllImport("dds.dll")]
public static extern int CalcDDtablePBN(DDTableDealPBNStruct tableDealPBN, ref DDTableResultsStruct tablep);

这是我的结构:

public struct DDTableDealPBNStruct
{
    public char[] cards;

    public DDTableDealPBNStruct(char[] pbnCards)
    {
        cards = pbnCards;
    }
}

public struct DDTableResultsStruct
{
    public short[,] resTable; /* 1st index is trump (0=Spades, 1=Hearts, 2=Diamonds, 3=Clubs, 4=No Trump 2nd index is declarer hand, 0=North, 1=East, 2=South, 3=West */
}

这就是我调用函数的方式:

const string _dealPBN = "N:QJT..AJ76.AKJ765 AK64.AKJ7654..98 32.T932.KQ32.T43 9875.Q8.T9854.Q2";
DDTableDealPBNStruct tdPBN = new DDTableDealPBNStruct(_dealPBN.ToCharArray());
DDTableResultsStruct results = new DDTableResultsStruct();
results.resTable = new short[5, 4];
CalcDDtablePBN(tdPBN, ref results);

当我运行程序时,这是我收到的错误消息:

SafeArrayTypeMismatchException 未处理。指定的数组不是预期的类型。

它没有提到哪个数组不好,但我猜它是 short[5,4] 数组。我尝试了不同的 [MarshalAs(UnmanagedType.blah)] 选项无济于事。谁能告诉我我做错了什么?老实说,我很难过。

我还尝试了几种不同的数组类型,int、uint、short、Int16 等,但同样无济于事。除非我错了,这是它抱怨的 char[] 数组?

先感谢您。

4

1 回答 1

1

您需要描述结构的布局。

[StructLayout(LayoutKind.Sequential)]
public struct DDTableResultsStruct
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
    public int[] resTable;
}

似乎没有办法说数组是二维的,所以我刚刚给出了数组的完整大小,就好像它是一维的一样。(在 C 中,多维数组在内存中连续布局。)请注意,元素类型是int,而不是short- 它是 32 位的。您也应该对其他结构执行相同的操作。

(未经测试的代码。)

于 2012-11-27T12:56:28.653 回答