2

dll に次の C コード署名があります。

extern __declspec(dllexport) unsigned char *
funct_name (int *w, int *h, char **enc, int len, unsigned char *text, int *lp, int *mp, int *ep)

C 関数は、w、h、enc、lp、mp、および ep を変更できます (ただし、後者の 3 つは null になる可能性があり、何もしません。

私はC#で以下を使用しています

[DllImport("iec16022ecc200.dll", EntryPoint = "iec16022ecc200", ExactSpelling = false, CharSet = CharSet.Ansi, SetLastError = true, CallingConvention=CallingConvention.Cdecl)]
            static extern IntPtr CallEncode(
            [In,Out,MarshalAs(UnmanagedType.LPArray)] Int32[] width,
            [In,Out,MarshalAs(UnmanagedType.LPArray)] Int32[] height,
            [In,Out,MarshalAs(UnmanagedType.LPStr)] ref StringBuilder encoding,
            int barcodeLen,
            [MarshalAs(UnmanagedType.LPStr)] StringBuilder barcode,
            IntPtr lenp,
            IntPtr maxp,
            IntPtr eccp
            );


public void Foo (string textToEncode,out int width, out int height) {
            StringBuilder text = new StringBuilder(textToEncode);
            StringBuilder encoding = new StringBuilder(new string('a', text.Length));

            Int32[] w = new Int32[1];
            Int32[] h = new Int32[1];


            string encodedStr = Marshal.PtrToStringAnsi(CallEncode(w, h, ref encoding, text.Length, text, (IntPtr)0, (IntPtr)0, (IntPtr)0));
            width = w[0];
            height = h[0];
}

SystemAccessViolation が発生していますが、いつ問題が発生するのか完全にはわかりません。

4

4 に答える 4

3

char* を受け取るアンマネージ メソッドに StringBuilder 参照を渡さないでください。StringBuilder のコンテンツはユニコード (wchar) です。

代わりに、StringBuilder パラメーターを IntPtr パラメーターに置き換え、Marshal.AllocHGlobal を使用して適切なサイズのバッファーを割り当てます。

また、「ref」を使用して StringBuilder をアンマネージ コードに渡すことは、.Net マーシャラーではサポートされていないと思います。

于 2009-04-29T18:46:43.277 に答える
1

StringBuilderoutまたはを使用して参照渡ししないでくださいref

    //...
    [In,Out,MarshalAs(UnmanagedType.LPStr)] ref StringBuilder encoding,
    //...

型のパラメーターrefからキーワードを削除します。それがおそらくあなたの原因です。encodingStringBuilderSystemAccessViolation

于 2011-11-04T16:41:11.667 に答える
1

「char ** enc」パラメーターは呼び出し先によって変更される可能性があると述べましたが、これにより「SystemAccessViolation」エラーが発生する可能性があります。StringBuilders の容量を超えない限り、呼び出し先は StringBuilder を逆参照および変更できます。

于 2009-04-29T18:54:55.550 に答える