关于dll返回字符串在C#下调用的问题

bakerwhy 2007-03-19 09:17:40
c++dll导出函数的原型:

extern "C" __declspec(dllexport) void say(void);
extern "C" __declspec(dllexport) LPTSTR Picker();

我开始这样在c#中调用

[DllImport("..\\mfcdll\\mfcdll.dll", EntryPoint = "say")]
public static extern void say();

[DllImport("..\\mfcdll\\mfcdll.dll", EntryPoint = "Picker")]
public static extern string Picker();
.........

say(); //ok!

string str = Picker();

MessageBox.Show(str); //error:display empty comment

........


我又在网上查找一些资料,有说用StringBuilder可以解决,我又用以下方法:

[DllImport("..\\mfcdll\\mfcdll.dll", EntryPoint = "Picker")]
public static extern StringBuilder Picker();
.........

say(); //ok!

StringBuilder sb = new StringBuilder();

sb = Picker();

MessageBox.Show(sb.ToString()); //error:出现异常并退出

........

因为我接触c#时间不长,也没有去仔细看StringBuilder的文档,我也不知道以上用法是否正确



最后我又换了以下方法
[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Unicode)]
public struct MyString
{
public IntPtr _str;
}

[DllImport("..\\mfcdll\\mfcdll.dll", EntryPoint = "Picker")]

public extern static void marshalFun(IntPtr ip);
........
IntPtr ip = Marshal.AllocHGlobal(128);
marshalFun(ip);
MyString mystr = (MyString)Marshal.PtrToStructure(ip, typeof(MyString));
string str = Marshal.PtrToStringUni(mystr._str);

MessageBox.Show(str); //此处任然显示空
Marshal.FreeHGlobal ;

.......


dll文件应该没有问题,在vc.net 2005 + WM5 SDK中使用正常,而在C#下调用时,第一个导出函数say()调用正常,而第二个函数picker()始终不能得到正确结果。

这个问题困扰我两天了,先谢谢大家了:-)
...全文
271 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
leixueqiyi 2007-03-19
  • 打赏
  • 举报
回复
用System.Text.Encoding.Default.GetBytes();方法比对一下
楼上那位说的很对
C++里面的字符串是存放在byte数组里的,需要知道他的编码才能得到字符串。
C#里string都是unicode编码的16位char数组。
你可以把byte重组成string
danjiewu 2007-03-19
  • 打赏
  • 举报
回复
C++里面的字符串是存放在byte数组里的,需要知道他的编码才能得到字符串。
C#里string都是unicode编码的16位char数组。
bakerwhy 2007-03-19
  • 打赏
  • 举报
回复
:(
bakerwhy 2007-03-19
  • 打赏
  • 举报
回复
自己顶
bakerwhy 2007-03-19
  • 打赏
  • 举报
回复
请大家帮帮忙
bakerwhy 2007-03-19
  • 打赏
  • 举报
回复
不管怎么说还是谢谢上面两位朋友,结贴了。
bakerwhy 2007-03-19
  • 打赏
  • 举报
回复
问题已经解决,我修改了dll导出函数:
extern "C" __declspec(dllexport) long Picker(char **strFile)
在c#中这样调用:
[DllImport("..\\mfcdll\\mfcdll.dll")]
public static extern int Picker(ref string filename);
...
string filename = "";
int iRes = Picker(ref filename);
MessageBox.Show(filename); //OK!
...

如果直接返回的话涉及到内存分配问题,直接获得的地址是没有意义的。
bakerwhy 2007-03-19
  • 打赏
  • 举报
回复
楼上的方法我也试过:
[DllImport("..\\mfcdll\\mfcdll.dll")]
public static extern byte[] Picker();
...

byte[] bb = Picker(); //这里就出现异常退出了,应该说还没有进到Picker()里面
string str = Encoding.Default.GetString(bb, 0, 255);
MessageBox.Show(str);

不知道代码是不是以上那么写,请指正,另外,我觉得picker()的c#声明的类型始终有问题,不知道什么类型可以对应得上。

110,533

社区成员

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

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

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