当前位置:编程学习 > C#/ASP.NET >>

c# 调用 c++ 的DLL 问题

--------------------编程问答-------------------- 没人会吗?急啊
--------------------编程问答-------------------- 请高手指点,请高手指点 --------------------编程问答-------------------- 无法读写受保护的内存,指针不对。

param.lpBuffer  这个你那里来的?直接c++的指针发过来的么?
发消息拷贝数据用WM_COPYDATA。 --------------------编程问答--------------------
引用 3 楼 small21 的回复:
无法读写受保护的内存,指针不对。

param.lpBuffer  这个你那里来的?直接c++的指针发过来的么?
发消息拷贝数据用WM_COPYDATA。


param.lpBuffer的结构体是:

[StructLayout(LayoutKind.Sequential)]
    public struct GlyParam
    {
        public int handle;
        public int dwErrorCode;
        public int dwMessageID;
        public int dwRequestID;
        public int ulSize;
        public IntPtr lpBuffer;
        public string szParamName;
    }

而param的值是通过回调函数返回来的:
private void FrmCallback(ref GlyParam returnParam)
{
  param = returnParam;
  。。。
}
param.lpBuffer的值是个指针地址:113476728

现在就是要把param.lpBuffer转换成GlyDepositCounter结构.

GlyDepositCounter glyDepositCounter = (GlyDepositCounter)Marshal.PtrToStructure(param.lpBuffer, typeof(GlyDepositCounter));
这个时候出错:Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

--------------------编程问答-------------------- dll和主程序的指针不能直接共享的,感觉会有问题,没这么用过。 --------------------编程问答-------------------- [MarshalAs(UnmanagedType.LPWStr)]//根据c++中的类型设置成一样的
public string szParamName;
--------------------编程问答-------------------- 1、GlyDepositCounter里面的定义又套了结构,而且还套了几层,这样会导致Marshal在分配大小时,无法计算。你可以用Marsh.sizeof(typeof(GlyDepositCounter))来测试看看。因为无法分配大小,自然就读写不进去了。
2、可以考虑将需要套结构的地方转换成类来做,然后进行封装。到最终没有套结构的地方,再使用字节转换成结构。这样才比较保险。
 public class ObjectSp
    {

        #region bytesToStruct
        /// <summary>
        /// Byte array to struct or classs.
        /// </summary>
        /// <param name="bytes">Byte array</param>
        /// <param name="type">Struct type or class type.
        /// Egg:class Human{...};
        /// Human human=new Human();
        /// Type type=human.GetType();</param>
        ///  <param name="startIndex">Byte array start index.</param>
        /// <returns>Destination struct or class.</returns>
        public static object bytesToStruct(byte[] bytes, Type type, int startIndex = 0)
        {

            int size = Marshal.SizeOf(type);//Get size of the struct or class.          
            if (bytes.Length < size)
            {
                return null;
            }
            IntPtr structPtr = Marshal.AllocHGlobal(size);//Allocate memory space of the struct or class. 
            Marshal.Copy(bytes, startIndex, structPtr, size);//Copy byte array to the memory space.
            object obj = Marshal.PtrToStructure(structPtr, type);//Convert memory space to destination struct or class.         
            Marshal.FreeHGlobal(structPtr);//Release memory space.    
            return obj;
        }
        #endregion
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public class GlyDepositCounter
    {
        public uint EventNumber;
        public Tm Time;
        public uint dwSquentialNo;
        public uint dwUserID;
        public GlyCounters DepositData;

        public GlyDepositCounter(byte[] buff)
        {
            int offset = 0;
            EventNumber = BitConverter.ToUInt32(buff, 0);
            offset += sizeof(uint);
            Time = (Tm)ObjectSp.bytesToStruct(buff, typeof(Tm), offset);
            offset += Marshal.SizeOf(typeof(Tm));
            dwSquentialNo = BitConverter.ToUInt32(buff, offset);
            offset += sizeof(uint);
            dwUserID = BitConverter.ToUInt32(buff, offset);
            offset += sizeof(uint);
            DepositData = 易做图yDepositData(buff, offset);
        }

        private GlyCounters 易做图yDepositData(byte[] buff, int offset)
        {
            GlyCounters DepositData = null;
            //仿照GlyDepositCounter进一步分析DepositData
            return DepositData;
        }
    }

3、建议增加CharSet和Pack参数,这样才能保证字节的对齐。比如[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi,Pack=1)]
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,