C++的dll函数在c#中调用获取不到值,请大家帮忙看下,谢谢!

时间:2022-01-09 19:00:03
下面的方法是c++写的DLL封装的方法,我要在c#里面引用然后使用:
int STDCALL SDT_ReadBaseMsg(int iPortID,unsigned char * pucCHMsg,unsigned int *	puiCHMsgLen,unsigned char * pucPHMsg,unsigned int  *puiPHMsgLen,int iIfOpen);


我在c#里面是这样写的:
 /// <summary>
        /// 读取卡的信息
        /// </summary>
        /// <param name="iPortID">端口号</param>
        /// <param name="pucManaInfo"></param>
        /// <param name="iIfOpen"></param>
        /// <returns></returns>
        [DllImport("IdCardDLL/sdtapi.dll")]
        private static extern int SDT_ReadBaseMsg(int iPortID, ref char[] pucCHMsg, ref int puiCHMsgLen, ref char[] pucPHMsg, ref int puiPHMsgLen, int iIfOpen);
        public unsafe static int ReadBaseMsg(int iPortID, ref char[] pucCHMsg, ref int puiCHMsgLen, ref char[] pucPHMsg, ref int puiPHMsgLen, int iIfOpen)
        {
            return SDT_ReadBaseMsg(iPortID,ref pucCHMsg, ref puiCHMsgLen,ref pucPHMsg, ref puiPHMsgLen, iIfOpen);
        }


然后Form窗体中这样调用:
  int puiCHMsgLen = 0;
            int puiPHMsgLen = 0;
             char[] pucCHMsg = new char[1024];
             char[] pucPHMsg = new char[1024];
           int i = ReadBaseMsg(1001, ref pucCHMsg, ref puiCHMsgLen, ref pucPHMsg, ref puiPHMsgLen, 1);

            MessageBox.Show(i.ToString() + "     " + pucCHMsg.Length);
              


调用之后发现,pucCHMsg根本获取不到值,请大家帮忙分析下,谢谢!

14 个解决方案

#1


设备均可正常得到端口值,没有其他的异常,DLL的引用路径也是对的。

#2


        private static extern int SDT_ReadBaseMsg(int iPortID,  StringBuilder pucCHMsg, ref int puiCHMsgLen, ...


int puiCHMsgLen = 1024;
StringBuilder pucCHMsg = new StringBuilder( puiCHMsgLen);
int i = ReadBaseMsg(1001, pucCHMsg, ref puiCHMsgLen, ...

#3


引用 2 楼 gomoku 的回复:
        private static extern int SDT_ReadBaseMsg(int iPortID,  StringBuilder pucCHMsg, ref int puiCHMsgLen, ...


int puiCHMsgLen = 1024;
StringBuilder pucCHMsg = new StringBuilder( puiCHMsgLen);
int i = ReadBaseMsg(1001, pucCHMsg, ref puiCHMsgLen, ...


我都换成了StringBuilder,仍然是空的,获取不到值,不过谢谢啦!

#4


有人帮忙看下么?谢谢了先

#5


你看下传参的类型对没有

#6


你试试[DllImport("IdCardDLL/sdtapi.dll",CharSet = CharSet.Ansi)]

#7


引用 6 楼 kkzhangyu 的回复:
你试试[DllImport("IdCardDLL/sdtapi.dll",CharSet = CharSet.Ansi)]


我已经这么写了,还是没有得到值。

 [DllImport("IdCardDLL/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall, EntryPoint = "SDT_ReadBaseMsg")]
        private static extern int SDT_ReadBaseMsg(int iPortID, ref byte pucCHMsg, ref int puiCHMsgLen, ref byte pucPHMsg, ref int puiPHMsgLen, int iIfOpen);
        public unsafe static int ReadBaseMsg(int iPortID, ref byte pucCHMsg, ref int puiCHMsgLen, ref byte pucPHMsg, ref int puiPHMsgLen, int iIfOpen)
        {
            return SDT_ReadBaseMsg(iPortID, ref pucCHMsg, ref puiCHMsgLen, ref pucPHMsg, ref puiPHMsgLen, iIfOpen);
        }

#8


debugview
慢慢调试  看看dll里面能接受到不
最好dll返回之前再输出下结果

#9


二代身份证PC端标准调用接口。

#10




[DllImport("IdCardDLL/sdtapi.dll", CharSet = CharSet.Ansi, EntryPoint = "SDT_ReadBaseMsg")]
        private static extern int SDT_ReadBaseMsg(int iPortID, StringBuilder pucCHMsg, ref int puiCHMsgLen, StringBuilder pucPHMsg, ref int puiPHMsgLen, int iIfOpen);
        public unsafe static int ReadBaseMsg(int iPortID, StringBuilder pucCHMsg, ref int puiCHMsgLen, StringBuilder pucPHMsg, ref int puiPHMsgLen, int iIfOpen)
        {
            return SDT_ReadBaseMsg(iPortID, pucCHMsg, ref puiCHMsgLen, pucPHMsg, ref puiPHMsgLen, iIfOpen);
        }

#11


StringBuilder 改成string ,反正是参数不对
个个的试

#12


从 C# 中传递一个缓冲区到 DLL 中,用以获取数据时,需要进行托管内存与非托管内存之间的转换。
1 char * 对应到 C# 为 IntPtr
2 从托管内存到非托管内存的转换为:
定义一个 byte[] buff,获取 IntPtr,
GCHandle gc = GCHandle.Alloc(buff, GCHandleType.Pinned);
IntPtr p = gc.AddrOfPinnedObject();
2 从非托管内存到托管内存的转换为:
Marshal.Copy(...) 系列方法其中一个

#13


楼主解决这个问题了吗,我也遇到相似的问题了,我的问题是结构体返回的值不完整,也就是说,这个结构体内,有的变量能够返回值,而有的变量没有返回值。

#14


C++和C#参数不匹配。

#1


设备均可正常得到端口值,没有其他的异常,DLL的引用路径也是对的。

#2


        private static extern int SDT_ReadBaseMsg(int iPortID,  StringBuilder pucCHMsg, ref int puiCHMsgLen, ...


int puiCHMsgLen = 1024;
StringBuilder pucCHMsg = new StringBuilder( puiCHMsgLen);
int i = ReadBaseMsg(1001, pucCHMsg, ref puiCHMsgLen, ...

#3


引用 2 楼 gomoku 的回复:
        private static extern int SDT_ReadBaseMsg(int iPortID,  StringBuilder pucCHMsg, ref int puiCHMsgLen, ...


int puiCHMsgLen = 1024;
StringBuilder pucCHMsg = new StringBuilder( puiCHMsgLen);
int i = ReadBaseMsg(1001, pucCHMsg, ref puiCHMsgLen, ...


我都换成了StringBuilder,仍然是空的,获取不到值,不过谢谢啦!

#4


有人帮忙看下么?谢谢了先

#5


你看下传参的类型对没有

#6


你试试[DllImport("IdCardDLL/sdtapi.dll",CharSet = CharSet.Ansi)]

#7


引用 6 楼 kkzhangyu 的回复:
你试试[DllImport("IdCardDLL/sdtapi.dll",CharSet = CharSet.Ansi)]


我已经这么写了,还是没有得到值。

 [DllImport("IdCardDLL/sdtapi.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall, EntryPoint = "SDT_ReadBaseMsg")]
        private static extern int SDT_ReadBaseMsg(int iPortID, ref byte pucCHMsg, ref int puiCHMsgLen, ref byte pucPHMsg, ref int puiPHMsgLen, int iIfOpen);
        public unsafe static int ReadBaseMsg(int iPortID, ref byte pucCHMsg, ref int puiCHMsgLen, ref byte pucPHMsg, ref int puiPHMsgLen, int iIfOpen)
        {
            return SDT_ReadBaseMsg(iPortID, ref pucCHMsg, ref puiCHMsgLen, ref pucPHMsg, ref puiPHMsgLen, iIfOpen);
        }

#8


debugview
慢慢调试  看看dll里面能接受到不
最好dll返回之前再输出下结果

#9


二代身份证PC端标准调用接口。

#10




[DllImport("IdCardDLL/sdtapi.dll", CharSet = CharSet.Ansi, EntryPoint = "SDT_ReadBaseMsg")]
        private static extern int SDT_ReadBaseMsg(int iPortID, StringBuilder pucCHMsg, ref int puiCHMsgLen, StringBuilder pucPHMsg, ref int puiPHMsgLen, int iIfOpen);
        public unsafe static int ReadBaseMsg(int iPortID, StringBuilder pucCHMsg, ref int puiCHMsgLen, StringBuilder pucPHMsg, ref int puiPHMsgLen, int iIfOpen)
        {
            return SDT_ReadBaseMsg(iPortID, pucCHMsg, ref puiCHMsgLen, pucPHMsg, ref puiPHMsgLen, iIfOpen);
        }

#11


StringBuilder 改成string ,反正是参数不对
个个的试

#12


从 C# 中传递一个缓冲区到 DLL 中,用以获取数据时,需要进行托管内存与非托管内存之间的转换。
1 char * 对应到 C# 为 IntPtr
2 从托管内存到非托管内存的转换为:
定义一个 byte[] buff,获取 IntPtr,
GCHandle gc = GCHandle.Alloc(buff, GCHandleType.Pinned);
IntPtr p = gc.AddrOfPinnedObject();
2 从非托管内存到托管内存的转换为:
Marshal.Copy(...) 系列方法其中一个

#13


楼主解决这个问题了吗,我也遇到相似的问题了,我的问题是结构体返回的值不完整,也就是说,这个结构体内,有的变量能够返回值,而有的变量没有返回值。

#14


C++和C#参数不匹配。