-2

C/C++ DLL SDK を使用すると、次のようになります。

    INT CmdGetAllLog( BYTE *bStream, UINT16 *nCount, const UINT8 nblk )

しかし、プロジェクトではc#を使用します。私はそれを次のように行います:

    [DllImport("C:\\PrBioApi.dll", EntryPoint = "CmdGetAllLog")]
    private static extern bool CmdGetAllLog(IntPtr bStream, ref UInt16 nCount, byte nblk);

そして私はそれを使用します:

                    int nMallocSize = Marshal.SizeOf(new LOG_RECORD()) * stuSystem.wLogCnt + 4096;
                    byte[] pRecord = new byte[nMallocSize];
                    IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(nMallocSize));
                    Marshal.Copy(pRecord, 0, p, pRecord.Length);

                    bGetSucc = CmdGetAllLog(p, ref nGet, nBlk++);

                    Marshal.FreeHGlobal(p);

しかし、うまくいきませんでした。誰でも私を助けることができますか?ありがとう。

4

1 に答える 1

0

マネージド配列とアンマネージド ポインターの間でコピーするコードが間違った場所にあります。アンマネージ関数の呼び出しの後である必要があります。

しかし、p/invoke マーシャラーに作業を任せるのも良いでしょう:

[DllImport(@"C:\PrBioApi.dll")]
private static extern bool CmdGetAllLog(
    byte[] bStream, 
    ref ushort nCount, 
    byte nblk
);

int nMallocSize = ...;
byte[] pRecord = new byte[nMallocSize];
bool bGetSucc = CmdGetAllLog(pRecord, ref nGet, nBlk++);

バイト配列は blittable であるため、マーシャラーは呼び出し中に配列を固定し、それをネイティブ コードに渡します。

他の 2 つのパラメーターが正しく渡されていると想定しています。インターフェイスの詳細をこれ以上指定していないため、間違っている可能性があります。nGetこれは、関数にバッファーの大きさを伝え、関数によってコピーされた量を返すために使用されると思います。質問で指定した場所がわかりませんnGet。私はあなたがそのビットを正しく理解したと信じています。

その他のコメント:

  1. DllImport属性で呼び出し規約を指定する必要がある場合があります。cdeclおそらくネイティブコードですか?
  2. 戻り値はINTネイティブ コードにありますが、にマップしましたbool。プロトコルがゼロ以外の戻り値が成功を意味する場合、それはおそらく問題ありません。しかし、戻り値がそれ以上を示している場合は、明らかに使用する必要がありますintint個人的には、ネイティブに忠実であり続けたいと思っています。
于 2013-05-22T05:26:43.840 に答える