C#调用DLL的问题(如何以传址方式传递一个结构数组?)

helloworld01 2007-01-30 10:41:03
各位大哥,我用VC做了一个DLL,其中有一个函数是这样的:
int _stdcall gsmParseMessageList(SM_PARAM* pMsg)
{
……………………
}
上面定义的SM_PARAM结构在C#中的定义如下:
public struct SM_PARAM
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string SCA;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string TPA;
public char TP_PID;
public char TP_DCS;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string TP_SCTS;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 160)]
public string TP_UD;
short index;
};
我定义了 SM_PARAM [] msg=new SM_PARAM [10] 这样一个数组,但是因为
C#默认不支持指针的,我要以传址的方式传递一个结构数组,在DLL如何声名?之前我试过
这样:
[DllImport("D:\\DLL\\temp\\Debug\\mmt.dll")]
public static extern int gsmParseMessageList (ref SM_PARAM [] msg);
但是这就相当于传递了一个二级指针了,只有将DLL中的int _stdcall gsmParseMessageList(SM_PARAM* pMsg)改为int _stdcall gsmParseMessageList(SM_PARAM** pMsg)才能正常运行,但我只要以传址的方式传递一个结构数组到gsmParseMessageList(SM_PARAM* pMsg)中,请问我要怎么做?希望大家帮帮忙,小弟感激不尽,谢谢!
...全文
2325 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
weile___c 2012-08-05
  • 打赏
  • 举报
回复
C#结构数组!还来个指针!...这段用C吧
C#不合适..
斯内科 2012-01-12
  • 打赏
  • 举报
回复
感谢26楼的朋友,解决了我的问题。
[DllImport("***.dll")]
public static extern short ReadRecord(IntPtr hCom, byte Adr, byte Cmd, ref RecordS Record, string FileName, byte Bz);
这个方法是批量读取,Record返回的是一个结构数组 传数组的第一个元素是正解ref Record[0]
helloworld01 2007-02-01
  • 打赏
  • 举报
回复
多谢名位的帮助,还是上面那位兄弟说得对,以前为了兼容别人做的DLL没办法,不过发现在C#这样调用太没效率,还是用C#自己重做吧.
wenbin0727 2007-01-31
  • 打赏
  • 举报
回复
mark!
zjh222 2007-01-31
  • 打赏
  • 举报
回复
牵强付会,用C++就用C++,用CSharp就用Csharp,互操作是微软向下兼容的策略,为什么不把时间放在上面
peterxuxu 2007-01-31
  • 打赏
  • 举报
回复
“未处理AccessViolationException,尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”这样的错误应该是数据保护。

最近也遇到过类似问题,不过是c++调用delphi的时候出现的。你尝试一下在C#内使用Array.Clear(test,0,65536);
先清零数据。
在C++中使用 void * 作为形参,然后c++内所有操作使用 强制类型转换后的指针自增、自减操作来完成。不知道这样的方式是否可以解决你的问题。
注册失败 2007-01-31
  • 打赏
  • 举报
回复
在你的结构体定义前面加上[StructLayout(LayoutKind.Sequential )]
然后再试试把你的数组改大一点传进去试试,有可能是数组越界哦
lingbo_wx 2007-01-30
  • 打赏
  • 举报
回复
up
helloworld01 2007-01-30
  • 打赏
  • 举报
回复
我刚试了,可以调用,谢谢各位,但是,我一运行就提示:"未处理AccessViolationException,尝试读取或写入受保护的内存。这通常指示其他内存已损坏。",请问如何解决?谢谢!
真相重于对错 2007-01-30
  • 打赏
  • 举报
回复
dll 声明
[dllimport.... ]
int gsmParseMessageList(IntPtr pMsg)
调用
SM_PARAM[] arr = ....


IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement ( arr,0);
gsmParseMessageList( ptr );
helloworld01 2007-01-30
  • 打赏
  • 举报
回复
上面这样做是不行的,因为在定义的DLL中只会认为你是传递一个结构,我要的是传递一个结构数组
tgl10 2007-01-30
  • 打赏
  • 举报
回复
ref params msg
Red_angelX 2007-01-30
  • 打赏
  • 举报
回复
ref
tesling 2007-01-30
  • 打赏
  • 举报
回复
友情一顶
helloworld01 2007-01-30
  • 打赏
  • 举报
回复
哪位高手可以帮帮忙阿?实在很急阿,谢谢啦
helloworld01 2007-01-30
  • 打赏
  • 举报
回复
顶!!!
helloworld01 2007-01-30
  • 打赏
  • 举报
回复
KingDomgps大哥,是不是我这里
SM_PARAM [] msg=new SM_PARAM [10] ;
gsmParseMessageList( ref msg[0]);
有什么问题?
helloworld01 2007-01-30
  • 打赏
  • 举报
回复
KingDomgps大哥,你的方法我也试过了,的确好用,不过还是会出现这个问题,因为我要返回多个值,将结果返回到SM_PARAM结构,所以不是因为我在gsmParseMessageList中修改了SM_PARAM结构引起这个错误?
注册失败 2007-01-30
  • 打赏
  • 举报
回复
试过我的方法没,我以前的问题就是这个方法解决的
使用一直正常
helloworld01 2007-01-30
  • 打赏
  • 举报
回复
小弟在此谢过各位大哥了,尤其是hdt大哥,我刚试了,还是会出现"未处理AccessViolationException,尝试读取或写入受保护的内存。这通常指示其他内存已损坏。",看来只能用UNSAFE了,非常感谢各位
加载更多回复(10)

110,536

社区成员

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

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

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