c# intPtr 转换为 string 的问题

lihui_life 2015-12-19 09:51:21
c++函数原型
 /// <summary>
/// 读卡
/// </summary>
///参数:int ReadCard(char *room, char *gate,char *stime, char *guestname, char *guestid, char *track1, char *track2, long *cardno, int *st, int *Breakfast);
///room [out]:字符串指针,接收返回的房号,建议10字节。
///gate [out]:字符串指针,接收返回的授权公共通道,可以为NULL。
///Guestname [out]:字符串指针,接收返回的客人姓名,可以为NULL。
///Guestid [out]:字符串指针,接收返回的客人ID,可以为NULL。
///track1 [out]:接收磁卡第1轨数据,可以为NULL。
///track2 [out]:接收磁卡第2轨数据,可以为NULL。
///Cardno [out]:长整形指针,接收返回的卡号,可以为NULL。
///St [out]:整形指针,接收返回的卡状态,1-正常使用,3-正常注销,4-遗失注销,5-损毁注销,6-自动注销。可以为NULL。
///Breakfast [in]: 整形指针,接收早餐券数量。可以为NULL。

//[DllImport("MainDll.dll", CharSet = CharSet.Ansi)]
// public static extern int ReadCard(ref string room, ref string gate, ref string stime, ref string guestname, ref string guestid, ref string track1, ref string track2, ref int cardno, ref int st);

[DllImport("MainDll.dll", CharSet = CharSet.Ansi)]
public static extern int ReadCard(ref IntPtr room, ref IntPtr gate, ref IntPtr stime, ref IntPtr guestname, ref IntPtr guestid, ref IntPtr track1, ref IntPtr track2, ref IntPtr cardno, ref IntPtr st);


调用
  IntPtr room = IntPtr.Zero;
IntPtr gate = IntPtr.Zero;
IntPtr stime = IntPtr.Zero;

IntPtr guestName = IntPtr.Zero;
IntPtr guesiID = IntPtr.Zero;
IntPtr track1 = IntPtr.Zero;
IntPtr track2 = IntPtr.Zero;
IntPtr cardNo = IntPtr.Zero;
IntPtr st = IntPtr.Zero;

int num = BLL.BLLADELCard.Init("");

int result = BLL.BLLADELCard.ReadCard(ref room, ref gate, ref stime, ref guestName, ref guesiID, ref track1, ref track2, ref cardNo, ref st);
string strRoom = Marshal.PtrToStringAnsi(room);


这样读取成功,room 拿到的数据时 825242161,
转换 string string strRoom = Marshal.PtrToStringAnsi(room); strRoom 的值为“”
求~~~ 什么问题呢?
...全文
1317 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
jyf19 2019-06-24
  • 打赏
  • 举报
回复
图片发错了
yangdeshun888 2017-05-17
  • 打赏
  • 举报
回复
引用 楼主 lihuioooo 的回复:
c++函数原型
 /// <summary>
        /// 读卡
        /// </summary>
        ///参数:int ReadCard(char *room, char *gate,char *stime, char *guestname, char *guestid, char *track1, char *track2, long *cardno, int *st, int *Breakfast);
        ///room [out]:字符串指针,接收返回的房号,建议10字节。
        ///gate [out]:字符串指针,接收返回的授权公共通道,可以为NULL。
        ///Guestname [out]:字符串指针,接收返回的客人姓名,可以为NULL。
        ///Guestid [out]:字符串指针,接收返回的客人ID,可以为NULL。
        ///track1 [out]:接收磁卡第1轨数据,可以为NULL。
        ///track2 [out]:接收磁卡第2轨数据,可以为NULL。
        ///Cardno [out]:长整形指针,接收返回的卡号,可以为NULL。
        ///St [out]:整形指针,接收返回的卡状态,1-正常使用,3-正常注销,4-遗失注销,5-损毁注销,6-自动注销。可以为NULL。
        ///Breakfast [in]: 整形指针,接收早餐券数量。可以为NULL。

        //[DllImport("MainDll.dll", CharSet = CharSet.Ansi)]
       // public static extern int ReadCard(ref string room, ref  string gate, ref string stime, ref string guestname, ref string guestid, ref  string track1, ref  string track2, ref  int cardno, ref  int st);

        [DllImport("MainDll.dll", CharSet = CharSet.Ansi)]
        public static extern int ReadCard(ref IntPtr room, ref  IntPtr gate, ref IntPtr stime, ref IntPtr guestname, ref IntPtr guestid, ref  IntPtr track1, ref  IntPtr track2, ref  IntPtr cardno, ref  IntPtr st);
调用
  IntPtr room = IntPtr.Zero;
            IntPtr gate = IntPtr.Zero;
            IntPtr stime = IntPtr.Zero;

            IntPtr guestName = IntPtr.Zero;
            IntPtr guesiID = IntPtr.Zero;
            IntPtr track1 = IntPtr.Zero;
            IntPtr track2 = IntPtr.Zero;
            IntPtr cardNo = IntPtr.Zero;
            IntPtr st = IntPtr.Zero;

            int num = BLL.BLLADELCard.Init("");

            int result = BLL.BLLADELCard.ReadCard(ref room, ref gate, ref stime, ref guestName, ref guesiID, ref track1, ref track2, ref cardNo, ref st);
            string strRoom = Marshal.PtrToStringAnsi(room);
这样读取成功,room 拿到的数据时 825242161, 转换 string string strRoom = Marshal.PtrToStringAnsi(room); strRoom 的值为“” 求~~~ 什么问题呢?
解决方法:这个 string strRoom = Marshal.PtrToStringAnsi(room);是可以转化为string的,如果你的为空,则说明dll传回来的字符串是空的,这个原因肯定是因为你返回的字符串是局部char*变量,你应当在char前加个static变量, 例如:static char* name;这样就不会返回空了。
  • 打赏
  • 举报
回复
825242161这个是指针指向的地址吧,不是什么room 如果是const char* 可以用string,函数内是不会再改变的 char*你要自己分配空间,一般用StringBuiler或者byte[],试试 ReadCard([MarshalAs(UnmanagedType.LPStr)] StringBuilder room, 其他类似 一般是不需要加ref的,除非函数内会对room重新赋值(并且要求调用者自己释放),而不是改变room引用的字符串 如果是COM组件,优先尝试用[MarshalAs(UnmanagedType.BStr)]
zym8210 2015-12-21
  • 打赏
  • 举报
回复
还有就是,你这个库是成熟的库吗。如果库里面,直接把指针,指向了一个局部变量,那肯定会空了
zym8210 2015-12-21
  • 打赏
  • 举报
回复
intptr类型就不用 ref了。
xian_wwq 2015-12-21
  • 打赏
  • 举报
回复
使用stringbuilder来对应char* 按照char数组的长度,初始化stringbuilder 原则上来讲api是谁使用,就是谁申请空间
白衣如花 2015-12-21
  • 打赏
  • 举报
回复
试试不要ref,直接intPtr
lihui_life 2015-12-21
  • 打赏
  • 举报
回复
引用 12 楼 dongxinxi 的回复:
825242161这个是指针指向的地址吧,不是什么room 如果是const char* 可以用string,函数内是不会再改变的 char*你要自己分配空间,一般用StringBuiler或者byte[],试试 ReadCard([MarshalAs(UnmanagedType.LPStr)] StringBuilder room, 其他类似 一般是不需要加ref的,除非函数内会对room重新赋值(并且要求调用者自己释放),而不是改变room引用的字符串 如果是COM组件,优先尝试用[MarshalAs(UnmanagedType.BStr)]
感谢 dongxinxi 用[MarshalAs(UnmanagedType.LPStr)] StringBuilder room 接收数据成功, 问题解决了, 直接用StringBuilder 是不行的,需要加[MarshalAs(UnmanagedType.LPStr)] 修饰 谢谢各位啦
crystal_lz 2015-12-20
  • 打赏
  • 举报
回复
把你所有的 ref IntPtr 换成 StringBuilder
孤独de猫 2015-12-20
  • 打赏
  • 举报
回复
把字符串接收的类型,改成StringBuilder,或string类型。
lihui_life 2015-12-19
  • 打赏
  • 举报
回复
引用 4 楼 sunny906 的回复:
不行,就用auto看看

[DllImport("MainDll.dll", CharSet = CharSet.Auto)]
Marshal.PtrToStringAuto
测试了 CharSet.Auto 和CharSet.Unicode 直接就报错了。 “System.AccessViolationException”类型的未经处理的异常在 mscorlib.dll 中发生 其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
sunny906 2015-12-19
  • 打赏
  • 举报
回复
写错了,应该是这样

[DllImport("MainDll.dll", CharSet = CharSet.Unicode)]
string    string strRoom = Marshal.PtrToStringUni(room);
sunny906 2015-12-19
  • 打赏
  • 举报
回复
不行,就用auto看看

[DllImport("MainDll.dll", CharSet = CharSet.Auto)]
Marshal.PtrToStringAuto
sunny906 2015-12-19
  • 打赏
  • 举报
回复
可能是编码问题,改成unicode看看

[DllImport("MainDll.dll", CharSet = CharSet.Unicode)]
string    string strRoom = Marshal.PtrToStringAnsi(room); 
lihui_life 2015-12-19
  • 打赏
  • 举报
回复
周六都休息了

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧