200分求助大神来解决个C#调用C++dll内函数问题

pengwen420107 2017-10-13 03:09:48
在湖南这边整个医保对接程序。公司的医疗软件是asp.net开发的BS程序,医保中心给的动态库dll是C++开发的,那么问题来了。

string err = "";
long ll_return;
int li_ret = -1; //函数返回值
string ls_server = "10.137.67.246";
int ll_port = 7001;
string ls_servlet = "Insur_XT/ProcessAll";

//初始化
gl_pinterface = newinterfacewithinit(ls_server, ll_port, ls_servlet);

string ls_func_id = "0"; //功能号

ll_return = Start(gl_pinterface, ls_func_id);
if (ll_return < 0)
return li_ret;//



if (put(gl_pinterface, 1, " oper_centerid", "430201") < 0)
return li_ret;
if (put(gl_pinterface, 1, " oper_hospitalid", "43020150574") < 0)
return li_ret;
if (put(gl_pinterface, 1, " oper_staffid", "sys") < 0)
return li_ret;


//设置参数
if (put(gl_pinterface, 1, " login_id", "43020150574") < 0)
return li_ret;
if (put(gl_pinterface, 1, " login_password", "43020150574") < 0)
return li_ret;

//运行
ll_return = run(gl_pinterface);



[DllImport("../bin/InterfaceHN.dll",
EntryPoint = "newinterfacewithinit",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern long newinterfacewithinit(string Addr, int Port, string Servlet);


[DllImport("../bin/InterfaceHN.dll",
EntryPoint = "put",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern long put(long p_inter, long row, string p_name, string p_value);

[DllImport("../bin/InterfaceHN.dll",
EntryPoint = "run",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern long run(long p_inter);




代码编译不报错,但是获取的返回值不对,医保中心使用PB开发的程序put()方法正常返回值是1,而我这段put()方法返回值为一长串数字,导致下面程序走不通,我照着他们PB程序翻译成C#的。。。。实在找不出问题,我现在怀疑我调用C++方法时传的参数类型不一样导致问题的,不知道是不是这样,来大神帮我看看。
下面这个是这个方法的开发文档,C++的。
还有谁有做过湖南这边创智公司的医保对接?
2.1.6long put(Interface *p_inter, long row, char *p_name, char *p_value)
该函数用来在一次接口调用中传入业务所需的参数,参数p_inter为函数newinterface()或者newinterfacewithinit的返回值,row为多行参数的行号,p_name为参数名称,以字符串小写表示,p_value为参数值,可以是字符串和数值型。返回-1表示没有Put成功,返回大于零表示Put成功 ,此值同时为当前的行号。如果入参有多个记录集,可用setresultset函数设置要传参数的记录集。
...全文
467 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
xinbeckham 2017-12-15
  • 打赏
  • 举报
回复
[DllImport("InterfaceHN.dll", EntryPoint = "newinterfacewithinit")] public static extern IntPtr NewInterfaceWithInit(string Addr, int Port, string Servlet); [DllImport("InterfaceHN.dll", EntryPoint = "put")] public static extern int Put(IntPtr hInterface, int row, string p_name, string p_value); 这样定义
Demons1874 2017-10-17
  • 打赏
  • 举报
回复
引用 13 楼 pengwen420107 的回复:
不行,测试不通
public static extern int put(IntPtr p_inter, int row, string p_name, string p_value); long p_inter = newinterface()或者是newinterfacewithinit() IntPtr pBuf = Marshal.AllocHGlobal(Marshal.SizeOf(p_inter)); Marshal.StructureToPtr(p_inter, pBuf, true); put(pBuf, xxx, xxx, xxx); 这样试试
pengwen420107 2017-10-17
  • 打赏
  • 举报
回复
引用 10 楼 Saleayas 的回复:
long put(Interface *p_inter, long row, char *p_name, char *p_value); 通常应该使用 long put(Interface *p_inter, long row, char const *p_name, char const *p_value); 否则尝试使用 StringBuilder,同时修改 CallConvertion。 [DllImport("../bin/InterfaceHN.dll", EntryPoint = "put", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern int put(IntPtr p_inter, int row, string p_name, string p_value);
不行,测试不通
  • 打赏
  • 举报
回复
引用 5 楼 pengwen420107 的回复:
[quote=引用 3 楼 Libby1984 的回复:] [quote=引用 2 楼 pengwen420107 的回复:] [quote=引用 1 楼 Libby1984 的回复:] 会不会是函数中long类型的原因,在C#中long是8个字节,但是用C++编译的dll中long不一定是8个字节的哦。 http://blog.csdn.net/love_x_you/article/details/42846993
那应该用什么类型呢?用string类型报错,错误:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。[/quote] 改成int 试试[/quote] 搞错了int不行,但是c++long是4字节,pb也是,但是C#是8字节的,可能是有问题,但不知道怎么改[/quote] 如果其他地方没错的话,你还是试试改这里吧。 你的put函数,要求的是传单个参数,前面两个参数是4个字节的整数,返回的也是4个字节。而C++中是long型,但是在C#中4个字节的整数是int,你试试这样改: [DllImport("../bin/InterfaceHN.dll", EntryPoint = "put", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int put(int p_inter, int row, string p_name, string p_value);
Demons1874 2017-10-16
  • 打赏
  • 举报
回复
你试试把newinterfacewithinit的返回值的地址传过去
ilikeff8 2017-10-16
  • 打赏
  • 举报
回复
public static extern int put(intptr p_inter, int row, string p_name, string p_value); int gl_pinterface = 123; IntPtr p_inter = new IntPtr(gl_pinterface);
Saleayas 2017-10-16
  • 打赏
  • 举报
回复
long put(Interface *p_inter, long row, char *p_name, char *p_value); 通常应该使用 long put(Interface *p_inter, long row, char const *p_name, char const *p_value); 否则尝试使用 StringBuilder,同时修改 CallConvertion。 [DllImport("../bin/InterfaceHN.dll", EntryPoint = "put", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern int put(IntPtr p_inter, int row, string p_name, string p_value);
pengwen420107 2017-10-16
  • 打赏
  • 举报
回复
引用 8 楼 xian_wwq 的回复:
CharSet = CharSet.Auto可以尝试使用CharSet.Ansi 因为c#默认使用Unicode,一样的char,c#中是2 byte,c中可能就是1个byte。 c中long在c#中用int来对应应该可以
刚试了,没用。 我还把char* 参数改成了IntPtr也没用,long类型改成Uint32,int改成Uint16 都没用
xian_wwq 2017-10-16
  • 打赏
  • 举报
回复
CharSet = CharSet.Auto可以尝试使用CharSet.Ansi 因为c#默认使用Unicode,一样的char,c#中是2 byte,c中可能就是1个byte。 c中long在c#中用int来对应应该可以
pengwen420107 2017-10-16
  • 打赏
  • 举报
回复
引用 6 楼 Libby1984 的回复:
[quote=引用 5 楼 pengwen420107 的回复:] [quote=引用 3 楼 Libby1984 的回复:] [quote=引用 2 楼 pengwen420107 的回复:] [quote=引用 1 楼 Libby1984 的回复:] 会不会是函数中long类型的原因,在C#中long是8个字节,但是用C++编译的dll中long不一定是8个字节的哦。 http://blog.csdn.net/love_x_you/article/details/42846993
那应该用什么类型呢?用string类型报错,错误:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。[/quote] 改成int 试试[/quote] 搞错了int不行,但是c++long是4字节,pb也是,但是C#是8字节的,可能是有问题,但不知道怎么改[/quote] 如果其他地方没错的话,你还是试试改这里吧。 你的put函数,要求的是传单个参数,前面两个参数是4个字节的整数,返回的也是4个字节。而C++中是long型,但是在C#中4个字节的整数是int,你试试这样改: [DllImport("../bin/InterfaceHN.dll", EntryPoint = "put", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int put(int p_inter, int row, string p_name, string p_value);[/quote] 早试过了,而且还报错,说“尝试读取或写入受保护内存。。。。。”
pengwen420107 2017-10-13
  • 打赏
  • 举报
回复
引用 3 楼 Libby1984 的回复:
[quote=引用 2 楼 pengwen420107 的回复:] [quote=引用 1 楼 Libby1984 的回复:] 会不会是函数中long类型的原因,在C#中long是8个字节,但是用C++编译的dll中long不一定是8个字节的哦。 http://blog.csdn.net/love_x_you/article/details/42846993
那应该用什么类型呢?用string类型报错,错误:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。[/quote] 改成int 试试[/quote] 搞错了int不行,但是c++long是4字节,pb也是,但是C#是8字节的,可能是有问题,但不知道怎么改
  • 打赏
  • 举报
回复
会不会是函数中long类型的原因,在C#中long是8个字节,但是用C++编译的dll中long不一定是8个字节的哦。 http://blog.csdn.net/love_x_you/article/details/42846993
pengwen420107 2017-10-13
  • 打赏
  • 举报
回复
引用 3 楼 Libby1984 的回复:
[quote=引用 2 楼 pengwen420107 的回复:] [quote=引用 1 楼 Libby1984 的回复:] 会不会是函数中long类型的原因,在C#中long是8个字节,但是用C++编译的dll中long不一定是8个字节的哦。 http://blog.csdn.net/love_x_you/article/details/42846993
那应该用什么类型呢?用string类型报错,错误:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。[/quote] 改成int 试试[/quote] 。。。。long都不行,你用int 长度都不够,
  • 打赏
  • 举报
回复
引用 2 楼 pengwen420107 的回复:
[quote=引用 1 楼 Libby1984 的回复:] 会不会是函数中long类型的原因,在C#中long是8个字节,但是用C++编译的dll中long不一定是8个字节的哦。 http://blog.csdn.net/love_x_you/article/details/42846993
那应该用什么类型呢?用string类型报错,错误:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。[/quote] 改成int 试试
pengwen420107 2017-10-13
  • 打赏
  • 举报
回复
引用 1 楼 Libby1984 的回复:
会不会是函数中long类型的原因,在C#中long是8个字节,但是用C++编译的dll中long不一定是8个字节的哦。 http://blog.csdn.net/love_x_you/article/details/42846993
那应该用什么类型呢?用string类型报错,错误:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

110,538

社区成员

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

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

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