1

C#ソリューションで使用したいC ++でコーディングされたクローズドソースのアンマネージDLLがあるため、P/Invokeを使用してクローズドソースDLL関数を呼び出すラッパーマネージDLLを作成しました。これは、param関数とint変数がない場合に非常にうまく機能します。ただし、文字列のcharの配列を含むパラメーターとしてstructの配列を受け取る、より複雑な関数を実行すると、System.ExecutionEngineExceptionが発生します。これが私が持っていたものです:

[StructLayout(LayoutKind.Sequential)]
public struct Target
{
    public int targetID;

    public string Label;
}

[DllImport("tyrfde.dll", EntryPoint = "tyrfdeGetTarget")]
public static extern int GetTarget(ref Target[] targets);

以下は、DLLのヘッダーファイルから得た情報です。

#define TARGET_LBL_SIZE   (256l)

typedef struct _tyrfdeTarget
{
    TInt32 TargetID;                   // integer signed 32bits
    TCharA Label[TARGET_LBL_SIZE];     // caracter
} tyrfdeTarget;

TInt32 __stdcall tyrfdeGetTargets(tyrfdeTarget* pTargets);

配列サイズがlongとして指定されている理由はよくわかりませんが、とにかくSizeConstはintのみを取ります。ここでいくつか検索した後、私が修正しようとしたものです。

[StructLayout(LayoutKind.Sequential, Size = 260), Serializable]
public struct Target
{
    public int targetID;

    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string Label;
}

[DllImport("tyrfde.dll", EntryPoint = "tyrfdeGetTargets")]
public static extern int GetTarget(ref Target[] targets);

しかし、私はまだ問題を抱えています。関数がCLRによって使用されるメモリの一部をクリアすると、この例外がスローされる可能性があることを読みました。残念ながら、それを確認することはできません。私のコードに明らかに間違っていて問題を引き起こす可能性のあるものがありますか?

4

2 に答える 2

2

うーん、あなたの問題はrefTarget[] targetsパラメータにあると思います。AFAIRこれは参照への参照であり、おそらく実際に必要なものではありません。

私はこれを試してみます:

[DllImport("tyrfde.dll", EntryPoint = "tyrfdeGetTargets")]
public static extern int GetTarget([Out, MarshalAs(UnmanagedType.LPArray)] Target[] targets);

たぶん、この記事は正しい宣言を見つけるのに役立ちます。

ここでは配列のサイズが明確ではないことに注意してください。通常、このような場合はパラメータもあり、プロパティを介して属性ref int lengthで参照できます。MarshalAsSizeParameterIndex

于 2009-12-02T14:56:38.687 に答える
0

1)TCharAが16ビットであることを確認しますか?それ以外の場合は、使用するwharCharSetも指定する必要があると思います。

2)この種のラッパーの記述は、C ++/CLIでははるかに簡単です。

于 2009-12-02T15:03:37.283 に答える