C#获取dll char*返回值

hanjindou123 2015-12-01 04:32:14
C:
extern "C" __declspec(dllexport) char * Show2()
{
unsigned char output[32] = { '1','2','3','4','5','6','7','8','9' };
unsigned char *show = &output[0];
char * show2 = (char *)show;
return show2;
}


C#

[DllImport(@"C:\Users\HJD\Documents\Visual Studio 2015\Projects\CUseDll\CUseDll\bin\Debug\DLLCPP.dll", CharSet = CharSet.Ansi, ExactSpelling = false)]
public static extern string Show2();

string receive = Show2();

执行到这里就崩溃了 求解。
...全文
396 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
hanjindou123 2015-12-04
  • 打赏
  • 举报
回复
引用 12 楼 xian_wwq 的回复:
[quote=引用 楼主 hanjindou123 的回复:] C: extern "C" __declspec(dllexport) char * Show2() { unsigned char output[32] = { '1','2','3','4','5','6','7','8','9' }; unsigned char *show = &output[0]; char * show2 = (char *)show; return show2; } C# [DllImport(@"C:\Users\HJD\Documents\Visual Studio 2015\Projects\CUseDll\CUseDll\bin\Debug\DLLCPP.dll", CharSet = CharSet.Ansi, ExactSpelling = false)] public static extern string Show2(); string receive = Show2(); 执行到这里就崩溃了 求解。
找错点了,错误不在p/invoke,而是错在c代码 c不能返回局部指针变量,要不用静态变量,要不把变量放到堆上去 [/quote] 谢谢你~
hanjindou123 2015-12-04
  • 打赏
  • 举报
回复
引用 13 楼 dongxinxi 的回复:
这样能返回一个指针吗? show2()调用后 unsigned char output[32] = { '1','2','3','4','5','6','7','8','9' };就会被回收吧,show2将变成一个游离指针,指向不明,得到的当然是乱码 这是致命的 另外一个问题,就是你的字符串没有用\0结尾,应该是 unsigned char output[32] = { '1','2','3','4','5','6','7','8','9', 0 }; C很多函数很少是返回一个内部分配空间的char*的,比如strcat() strcpy(),sprintf()第一参数都是需要调用者自己传入一个char*来作为buffer,然后再返回指向这个字符串的指针便于后续操作 所以两个办法: 1.参照上面几个函数,上调用者传char[]进来,对应的就是C#中传StringBulider 2.改成堆中分配空间,当然最后要由调用方来释放,在函数前面用__cdecl来声明调用约定 unsigned char output[32] = { '1','2','3','4','5','6','7','8','9', 0 }; 改成 char *show2 = (char*)malloc(32); strcpy_s(show2, 32, "123456789"); 常量字符串自动以\0结尾 return show2; 就行了,
谢谢 ~~
hanjindou123 2015-12-04
  • 打赏
  • 举报
回复
引用 17 楼 shingoscar 的回复:
c的代码就是错的,怎么可以返回局部变量的指针,先把基础打好吧
嗯,那之后我试了 之前写C的时候没大注意 谢谢楼上所有人咯~~ 参考了下 搞定了
Poopaye 2015-12-02
  • 打赏
  • 举报
回复
c的代码就是错的,怎么可以返回局部变量的指针,先把基础打好吧
本拉灯 2015-12-02
  • 打赏
  • 举报
回复
char * show2 = (char *)show; 你这写的有问题吧,指针的指针??
Saleayas 2015-12-02
  • 打赏
  • 举报
回复
C 程序不要返回局部变量。 如果使用静态的变量,那么使用 IntPtr ,然后使用 Marshal 方法读取,并且不需要示释放。 如果使用堆变量。那么使用 SysAllocString 或者使用 CoTaskMemAlloc。 使用在托管代码使用 MashalAs 特性设置返回的 String。
  • 打赏
  • 举报
回复
调用方要调用free()来释放非托管堆
  • 打赏
  • 举报
回复
这样能返回一个指针吗? show2()调用后 unsigned char output[32] = { '1','2','3','4','5','6','7','8','9' };就会被回收吧,show2将变成一个游离指针,指向不明,得到的当然是乱码 这是致命的 另外一个问题,就是你的字符串没有用\0结尾,应该是 unsigned char output[32] = { '1','2','3','4','5','6','7','8','9', 0 }; C很多函数很少是返回一个内部分配空间的char*的,比如strcat() strcpy(),sprintf()第一参数都是需要调用者自己传入一个char*来作为buffer,然后再返回指向这个字符串的指针便于后续操作 所以两个办法: 1.参照上面几个函数,上调用者传char[]进来,对应的就是C#中传StringBulider 2.改成堆中分配空间,当然最后要由调用方来释放,在函数前面用__cdecl来声明调用约定 unsigned char output[32] = { '1','2','3','4','5','6','7','8','9', 0 }; 改成 char *show2 = (char*)malloc(32); strcpy_s(show2, 32, "123456789"); 常量字符串自动以\0结尾 return show2; 就行了,
xian_wwq 2015-12-02
  • 打赏
  • 举报
回复
引用 楼主 hanjindou123 的回复:
C: extern "C" __declspec(dllexport) char * Show2() { unsigned char output[32] = { '1','2','3','4','5','6','7','8','9' }; unsigned char *show = &output[0]; char * show2 = (char *)show; return show2; } C# [DllImport(@"C:\Users\HJD\Documents\Visual Studio 2015\Projects\CUseDll\CUseDll\bin\Debug\DLLCPP.dll", CharSet = CharSet.Ansi, ExactSpelling = false)] public static extern string Show2(); string receive = Show2(); 执行到这里就崩溃了 求解。
找错点了,错误不在p/invoke,而是错在c代码 c不能返回局部指针变量,要不用静态变量,要不把变量放到堆上去
呔妖怪来嘛 2015-12-02
  • 打赏
  • 举报
回复
extern "C" __declspec(dllexport) char * Show2() { unsigned char output[32] = { '1','2','3','4','5','6','7','8','9' }; unsigned char *show = &output[0]; char * show2 = (char *)show; return show2; } 这段代码就不对 ,有这么返回指针的吗 用malloc
hanjindou123 2015-12-02
  • 打赏
  • 举报
回复
引用 9 楼 byronqiji 的回复:
[quote=引用 8 楼 hanjindou123 的回复:] [quote=引用 2 楼 byronqiji 的回复:] 使用unsafe 来获取char*吧 unsafe { char* c = Show2(); }
这样如何获取数组内容呢?[/quote] unsafe { char* c = Show2(); for (int i = 0; i < 32; ++i, ++c) { Consol.WriteLine(c); } }[/quote] 这样都是乱码了
byronqiji 2015-12-01
  • 打赏
  • 举报
回复
引用 8 楼 hanjindou123 的回复:
[quote=引用 2 楼 byronqiji 的回复:] 使用unsafe 来获取char*吧 unsafe { char* c = Show2(); }
这样如何获取数组内容呢?[/quote] unsafe { char* c = Show2(); for (int i = 0; i < 32; ++i, ++c) { Consol.WriteLine(c); } }
hanjindou123 2015-12-01
  • 打赏
  • 举报
回复
引用 2 楼 byronqiji 的回复:
使用unsafe 来获取char*吧 unsafe { char* c = Show2(); }
这样如何获取数组内容呢?
hanjindou123 2015-12-01
  • 打赏
  • 举报
回复
引用 6 楼 u012948520 的回复:
引用 5 楼 hanjindou123 的回复:
, CharSet = CharSet.Ansi这个特性加上也是乱码吗
是的 [DllImport(@"C:\Users\HJD\Documents\Visual Studio 2015\Projects\CUseDll\CUseDll\bin\Debug\DLLCPP.dll",CallingConvention = CallingConvention.Cdecl,CharSet = CharSet.Ansi)] public static extern IntPtr Show2(); 现在是这样 接收我写了几种都不行 直接用console.write(show2())是奇怪的一串数字 tring receive = Marshal.PtrToStringBSTR(Show2()); string receive = Marshal.PtrToStringAnsi(Show2()); 也不行 就直接是乱码了
白衣如花 2015-12-01
  • 打赏
  • 举报
回复
引用 5 楼 hanjindou123 的回复:
, CharSet = CharSet.Ansi这个特性加上也是乱码吗
hanjindou123 2015-12-01
  • 打赏
  • 举报
回复
引用 4 楼 u012948520 的回复:
[DllImport("xxx.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr Show2();
这个返回的是乱码,怎么解决呢?
白衣如花 2015-12-01
  • 打赏
  • 举报
回复
[DllImport("xxx.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr Show2();
hanjindou123 2015-12-01
  • 打赏
  • 举报
回复
使用intptr获取出来是别的数字
byronqiji 2015-12-01
  • 打赏
  • 举报
回复
使用unsafe 来获取char*吧 unsafe { char* c = Show2(); }
hanjindou123 2015-12-01
  • 打赏
  • 举报
回复
stringbulider也不行

110,539

社区成员

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

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

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