0

まず第一に、私はこれに対する答えを高低で検索しました。何かを見つけたとき、それは C++ プログラマではない私にとっては意味不明なものです。プログラミングは私にとって単なる趣味です。

役立つ場合に備えて、C# winforms プロジェクトで Visual Studio 2010 Ultimate を使用しています。

問題は、アンマネージ DLL (Bo Haglund の Double Dummy Solver) の関数を使用しようとしていることです。彼の readme は役に立たず、DLL の使用方法に関する記事は驚くほど少ない (つまり、まったくない)。

使用したい DLL 内の関数のプロトタイプがあります。

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

ポインターについてはよくわかりませんが、C# では "ref" を使用するだろうと推測しました。

関数に関する彼の readme は次のとおりです。

CalcDDテーブル

CalcDDtable は、20 のトランプ スーツ/ディクレアラー ハンドの組み合わせすべてについて、最初の 52 枚のカードのダブル ダミー値を計算します。

CalcDDtable を呼び出す前に、" ddTableResults" 型の構造を宣言する必要があります。CalcDDtable はステータス整数を返します。「障害なし」は、DLL が「ddTableResults」型構造で二重のダミー スコアを提供することを意味します。ステータス コード:
1 = 障害なし。その他のステータス コードはエラーであり、コードは SolveBoard ステータス コードと同じです。

構造体「ddTableDeal」は、分析される配られたカードを定義します。struct ddTableDeal { unsigned int カード[4][4]; /* 1 番目のインデックスはハンド、2 番目のインデックスはスーツ、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;
}

配列が 2 次元であると言う方法はないようです。そのため、1 次元であるかのように配列のフル サイズを指定しました。(C では、多次元配列はメモリ内で連続して配置されます。) 要素の型はintではなく、short32 ビットであることに注意してください。他の構造体についても同じことを行う必要があります。

(テストされていないコード。)

于 2012-11-27T12:56:28.653 に答える