C#程序调用C++开发的返回字符串dll的问题

tangtang02520 2010-01-22 03:59:17
一个用C++语言编写的dll,包含一个函数WriteData,函数原型如下:
bool(int* recordNo,char* MeterArr,double* CurRecord,char* Name,int NameLen)
主调函数通过参数Name传递一个字符串给WriteData函数处理,处理后的几个值包含MeterArr等返回给主调函数使用。
用C++语言编写的调试程序能够正常调用此dll。

但是用C#程序调用时出现问题,char* 类型的参数返回值为null,其他几个参数 int*、double*和int都正常。
C#调用部分语句如下:

[DllImport("TestDLL.dll", EntryPoint = "WriteData", CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern bool WriteData(out int recordNo, out string MeterArr, out double CurRecord,
string Name, int NameLen);

请帮忙分析原因并说明解决办法,多谢!
...全文
1039 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
tangtang02520 2010-01-22
  • 打赏
  • 举报
回复
问题解决了,谢谢各位!
如果要传进去值用string;如果要返回值用StringBuilder。确实是对的!

问题出在C++函数源代码里
用MeterArr="aaaa";不行
改成 for(int i=0;i<4;i++)
*(MeterArr+i) = 'a';
就可以了。晕~~
tangtang02520 2010-01-22
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 soaringbird 的回复:]
MeterArr用来传出什么内容?如果不是字符串,就用byte[]吧,注意不要ref或out。
[/Quote]
是字符串
tangtang02520 2010-01-22
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 yangglemu 的回复:]
平台调用字符串指针,如果是传进去值,用string,如果要返回值,用StringBuilder
我看你的调用方式没有问题啊,你检查一下函数的返回值(我怀疑是函数没有调用成功)
TestDll = WriteData(out recordNo,MeterArr, out CurRecord,Name, NameLen);
Console.WriteLine(TestDll);看看是个啥
[/Quote]

WriteData函数调用成功了,调用WriteData后 TestDll 的值由FALSE 变为TRUE
soaringbird 2010-01-22
  • 打赏
  • 举报
回复
也要事先分配足够空间。
soaringbird 2010-01-22
  • 打赏
  • 举报
回复
MeterArr用来传出什么内容?如果不是字符串,就用byte[]吧,注意不要ref或out。
  • 打赏
  • 举报
回复
平台调用字符串指针,如果是传进去值,用string,如果要返回值,用StringBuilder
我看你的调用方式没有问题啊,你检查一下函数的返回值(我怀疑是函数没有调用成功)
TestDll = WriteData(out recordNo,MeterArr, out CurRecord,Name, NameLen);
Console.WriteLine(TestDll);看看是个啥
tangtang02520 2010-01-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 xujiaoxiang 的回复:]
  [DllImport("ZRDLL.dll", EntryPoint = "WriteData", CharSet = CharSet.Ansi,  CallingConvention = CallingConvention.StdCall)]
        public static extern bool WriteData(out int recordNo,[Out, MarshalAs(UnmanagedType.LPStr)]string MeterArr, out double CurRecord, string Name, int NameLen);

试试这样?
[/Quote]
这样调试能通过,但是调用动态函数前后MeterArr的值没有变化,还不符合要求。
xujiaoxiang 2010-01-22
  • 打赏
  • 举报
回复
[DllImport("ZRDLL.dll", EntryPoint = "WriteData", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern bool WriteData(out int recordNo,[Out, MarshalAs(UnmanagedType.LPStr)]string MeterArr, out double CurRecord, string Name, int NameLen);

试试这样?

tangtang02520 2010-01-22
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 chrisak 的回复:]
引用 4 楼 tangtang02520 的回复:
感谢几位回复,能说具体点吗?我用StringBulder试过了 不行。用ref也不行
StringBuilder 不行?你怎么调用的?事先分配缓冲区了没?
StringBuilder不用ref.
[/Quote]

[DllImport("ZRDLL.dll", EntryPoint = "WriteData", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern bool WriteData(out int recordNo,StringBuilder MeterArr, out double CurRecord, string Name, int NameLen);

bool TestDll;
double CurRecord;
int recordNo,NameLen;
string Name;
StringBuilder MeterArr = new StringBuilder(12);
recordNo = 1;
CurRecord = 1.5;
NameLen = 10;
Name = "test";
TestDll = WriteData(out recordNo,MeterArr, out CurRecord,Name, NameLen);
ChrisAK 2010-01-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 tangtang02520 的回复:]
感谢几位回复,能说具体点吗?我用StringBulder试过了 不行。用ref也不行
[/Quote]StringBuilder 不行?你怎么调用的?事先分配缓冲区了没?
StringBuilder不用ref.
tangtang02520 2010-01-22
  • 打赏
  • 举报
回复
MeterArr 是在动态函数里处理得到的字符串,要返回给主调函数一个值,它的值调用动态函数前后有变化;
Name 是主调函数传递给动态函数的参数,其值不变。
ttllxx 2010-01-22
  • 打赏
  • 举报
回复
为什么要用out呢?好像不需要吧。
tangtang02520 2010-01-22
  • 打赏
  • 举报
回复
感谢几位回复,能说具体点吗?我用StringBulder试过了 不行。用ref也不行
flyerwing 2010-01-22
  • 打赏
  • 举报
回复
StringBulder MeterArr
应该对了
qqiuzaihui 2010-01-22
  • 打赏
  • 举报
回复
soaringbird 2010-01-22
  • 打赏
  • 举报
回复
StringBulder MeterArr

110,534

社区成员

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

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

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