dll是delphi写的,某函数参数是array of byte,我用ref byte[],intptr,stringbuilder传过去我构建好的byte[],总是报内存读写错误。请指教啊。。

解决方案 »

  1.   

    去掉ref 看看
    我估计是delphi操作了byte[]数组
      

  2.   

    我记得要将托管对象传递给非托管函数调用,在C#中还必须固定地址才行,对于值类型,因为只是值传递,因此不需要固定内存地址,但是数组就不同了,用过指针的都知道fixed关键字,为了防止内存被动态回收,而函数参数传递则是用MarshalAs来固定,例如:
    [DllImport("XXX.DLL", CharSet = CharSet.Auto)]
    static extern int testBytes([MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]byte[] bytes);
      

  3.   


    之前就试过了,加了ref报内存错误,不加ref报引擎错误
      

  4.   


    你声明的这个invoke,会报MarshalAs(UnmanagedType.ByValArray, SizeConst = 256只能用在struct的声明中,不能用在参数的声明中
      

  5.   

    好像那个SizeConst不能加,我找了一个微软的dll的定义,你先看下,参考下:
    [SuppressUnmanagedCodeSecurity, SecurityCritical, DllImport("QCall", CharSet=CharSet.Unicode)]
    private static extern void DecryptKey(SafeKeyHandle pKeyContext, [MarshalAs(UnmanagedType.LPArray)] byte[] pbEncryptedKey, int cbEncryptedKey, [MarshalAs(UnmanagedType.Bool)] bool fOAEP, ObjectHandleOnStack ohRetDecryptedKey);internal static class JitHelpers
    {
        // Fields
        internal const string QCall = "QCall";    // Methods
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), SecurityCritical]
        internal static ObjectHandleOnStack GetObjectHandleOnStack<T>(ref T o) where T: class
        {
            TypedReference reference = __makeref(o);
            return new ObjectHandleOnStack(reference.GetPointerOnStack());
        }
    //部分代码省略
    }
    [StructLayout(LayoutKind.Sequential)]
    internal struct ObjectHandleOnStack
    {
        private IntPtr m_ptr;
        internal ObjectHandleOnStack(IntPtr pObject)
        {
            this.m_ptr = pObject;
        }
    }  
      

  6.   

    这是调用代码,可见那个ObjectHandleOnStack是用来处理byte[]返回值用的,连初始化都不需要,就可以获得一个非托管分配内存的字节数组了。[SecuritySafeCritical]
    public byte[] Encrypt(byte[] rgb, bool fOAEP)
    {
        if (rgb == null)
        {
            throw new ArgumentNullException("rgb");
        }
        this.GetKeyPair();
        byte[] o = null;
        EncryptKey(this._safeKeyHandle, rgb, rgb.Length, fOAEP, JitHelpers.GetObjectHandleOnStack<byte[]>(ref o));
        return o;
    }
      

  7.   


    不得行,那只是传个intptr,还是报错
      

  8.   

    delphi的原型是啥?你用C++调用报错吗?
      

  9.   


    原型形参就是array of byte
      

  10.   

    VC的dll与delphi的dll原型定义是不同的,
    不能套用VC的经验
      

  11.   

    delphi参数类型PByte
    对应C#的ref byte[]
      

  12.   


    原型是对方给我的,delphi写的,就是array of byte,不是pbyte。我ref byte[]过去就报内存读写错误。。业务就是我组织一段byte[]扔给他处理,哪知道根本无法传递不知道怎么解决,sigh
      

  13.   

    array of byte貌似是Dephi定义的独特的数组类型,dll应该使用标准的C类型的数组,否则要准确的知道它在Dephi的实现方式,然后在C#中模拟它
    建议这样:叫对方改接口,改PByte或者其它标准数据结构。要不然NND你给我个VC调用例啊,我可以自己改C#的!
      

  14.   

    Dephi要写出可供类C语言调用的dll要额外考虑更多问题,如果dll提供者没能提供VC调用例,我是不敢去信任它
      

  15.   


    你说的很有道理,我让对方改为pbyte试试。用pbyte的话,我这边是不是ref byte[]就对应了?