尝试读取或写入受保护的内存。这通常指示其他内存已损坏

豆丁_ 2011-10-28 10:23:52
在C#调用C++的DLL的时候提示出现此问题

int tempLength=10;
float[] speedList = new float[tempLength];
float[] fypList = new float[tempLength];

for (int i = 0; i < tempLength; i++)
{

speedList[i] = float.Parse(vibDateList[i].RPM.ToString());
fypList[i] = float.Parse(vibDateList[i].FONEX.ToString());

}
StringBuilder[] symIDList = new StringBuilder[5];
symIDList.SetValue(new StringBuilder(1024), 0);
symIDList.SetValue(new StringBuilder(1024), 1);
symIDList.SetValue(new StringBuilder(1024), 2);
symIDList.SetValue(new StringBuilder(1024), 3);
symIDList.SetValue(new StringBuilder(1024), 4);
DiagnosisPro(speedList, fypList, 6000F, 50F, ref symIDList);



[DllImport(@"E:\DigsAlgorithm.dll")]
public static extern void DiagnosisPro(float[] speedList, float[] fypList, float StaticSpeed, float StaticFyp, ref StringBuilder[] symIDList);





void _stdcall DiagnosisProc(float speed[AryCount],
float fyb[AryCount], //swing list in time section
float StaticSpeed, //Speed condition
float StaticFyp, string ret[AryCount]);


说明, 使用StringBuilder并且分配一个固定长度是搜索了相关的文档说建议写固定长度,所以才这么写,不知道有何错误,还望各位达人帮忙查看
...全文
118 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
wgczxm 2011-10-31
  • 打赏
  • 举报
回复
楼上说的很有道理,我在调用c的dll的时候用的就是c里面用的就是char*在c#中使用string等同于char*,是可以用的。你让你们的c++工程师在外面做一个函数包处理一下在拿到.net中进行使用。
豆丁_ 2011-10-28
  • 打赏
  • 举报
回复
自己UP
豆丁_ 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gomoku 的回复:]
引用楼主 qiao5213 的回复:
……
void _stdcall DiagnosisProc(..., string ret[AryCount]);

那个string(可能是std::string)C#不支持。
[/Quote]

我该如何去改?谢谢
gomoku 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 qiao5213 的回复:]
……
void _stdcall DiagnosisProc(..., string ret[AryCount]);
[/Quote]
那个string(可能是std::string)C#不支持。
sdl2005lyx 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gomoku 的回复:]

引用楼主 qiao5213 的回复:
……
void _stdcall DiagnosisProc(..., string ret[AryCount]);

那个string(可能是std::string)C#不支持。
[/Quote]

这个说的有理,问题就处在这里!你需要在C++那边做些技术处理:因为net的互操作只能支持标准的类型,这个在MSDN有详细说明!增加一个C++的函数,给现有的包装一下:改成字符串指针数字
void _stdcall NewDiagnosisProc(float speed[AryCount], float fyb[AryCount], float StaticSpeed,
float StaticFyp, char* ret[AryCount]);

在这个函数里面处理char* ret[AryCount]与string ret[AryCount],在调用原来的函数!


C#这边:映射的是新的函数NewDiagnosisProc

[DllImport(@"E:\DigsAlgorithm.dll", EntryPoint="NewDiagnosisProc",CallingConvention = CallingConvention.StdCall)]
public static extern void DiagnosisPro(float[] speedList, float[] fypList, float StaticSpeed, float StaticFyp, [In,Out]string[] symIDList);



注意DllImport里面的各个属性!

wgczxm 2011-10-28
  • 打赏
  • 举报
回复
你的这个问题,主要是string[]数组传递出现的错误,因为在c#中,内存的分配都是由CLR自己来分配和回收的,所以你这样的dll,这个数组的内存分配就会造成内存的读写问题。我之前尝试过是没有办法越过的,你从这方面想点点子吧,我技术不高,就爱莫能助了。
豆丁_ 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 xfreyes 的回复:]
ref StringBuilder[] symIDList 改成string[] symIDList 试试
[/Quote]

问了C++那边的开发人员,方法需要返回值,但是不支持string[]。所以使用ref
豆丁_ 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wgczxm 的回复:]
我在用c#调用c的dll的时候也出现了类似的问题。你尝试下面的写法
[DllImport(@"E:\DigsAlgorithm.dll", CallingConvention = CallingConvention.Cdecl)]
不过这个方法一般是针对出现堆栈不对称问题。

你上述问题的出现,原因是 在c语言中一般封闭和保护都没有C#编译器好,这也造成了c#代码的灵活性下降了。出现这个……
[/Quote]

更改[DllImport(@"E:\DigsAlgorithm.dll", CallingConvention = CallingConvention.Cdecl)]
这个写法后也是错误,C++开发人员说自己调用是没问题的...
继续郁闷
wgczxm 2011-10-28
  • 打赏
  • 举报
回复
我在用c#调用c的dll的时候也出现了类似的问题。你尝试下面的写法
[DllImport(@"E:\DigsAlgorithm.dll", CallingConvention = CallingConvention.Cdecl)]
不过这个方法一般是针对出现堆栈不对称问题。

你上述问题的出现,原因是 在c语言中一般封闭和保护都没有C#编译器好,这也造成了c#代码的灵活性下降了。出现这个问题,和你调用的dll中含有string[]有关,我之前有这样的参数的时候也一直是内存错误,因为我本来就不需要数组,改成单个变量就没有错误了。或者你先把你的dll放在c环境下调用,看看是不是dll本身就有问题,而不是c#和c之间结合的问题。
xfreyes 2011-10-28
  • 打赏
  • 举报
回复
ref StringBuilder[] symIDList 改成string[] symIDList 试试

110,534

社区成员

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

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

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