您的位置:程序门 -> .net技术 -> c#



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


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


c#调用dll的问题(如何以传址方式传递一个结构数组?)
发表于: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)中,请问我要怎么做?希望大家帮帮忙,小弟感激不尽,谢谢!
发表于:2007-01-30 10:59:251楼 得分:0
顶!!!
发表于:2007-01-30 11:03:352楼 得分:0
哪位高手可以帮帮忙阿?实在很急阿,谢谢啦
发表于:2007-01-30 11:04:263楼 得分:0
友情一顶
发表于:2007-01-30 11:15:204楼 得分:0
ref
发表于:2007-01-30 11:32:295楼 得分:0
ref   params   msg
发表于:2007-01-30 11:39:426楼 得分:0
上面这样做是不行的,因为在定义的dll中只会认为你是传递一个结构,我要的是传递一个结构数组
发表于:2007-01-30 11:44:477楼 得分:0
dll   声明
[dllimport....   ]
int   gsmparsemessagelist(intptr   pmsg)
调用
sm_param[]   arr   =   ....


intptr   ptr     =   marshal.unsafeaddrofpinnedarrayelement   (   arr,0);
gsmparsemessagelist(   ptr   );
发表于:2007-01-30 12:05:158楼 得分:0
我刚试了,可以调用,谢谢各位,但是,我一运行就提示: "未处理accessviolationexception,尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 ",请问如何解决?谢谢!
发表于:2007-01-30 12:30:469楼 得分:0
up
发表于:2007-01-30 13:24:3310楼 得分:0
struct的   c++   声明
发表于:2007-01-30 13:31:1911楼 得分:0
hdt大哥,请问要改哪里阿?麻烦您了,可说明一下吗,非常感谢!这是我在c#中的struct
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;
};
发表于:2007-01-30 13:32:2412楼 得分:0
实在不行就unsafe吧~~
发表于:2007-01-30 13:35:1713楼 得分:0
到了最后关头,再用吧,谢谢各位!
发表于:2007-01-30 13:36:3514楼 得分:0
把c++的struct声明贴出来
发表于:2007-01-30 13:41:0215楼 得分:0
c++的struct声明是这样的:
typedef   struct   {
char   sca[16];
                  char   tpa[16];
                  char   tp_pid;
char   tp_dcs;
char   tp_scts[16];
char   tp_ud[160];
short   index;
}   sm_param;
发表于:2007-01-30 13:44:3116楼 得分:0
定义方式:
[dllimport( "d:\\dll\\temp\\debug\\mmt.dll ")]
public   static   extern   int   gsmparsemessagelist   (ref   sm_param   msg);

调用方式:
sm_param   []   msg=new   sm_param   [10]   ;
gsmparsemessagelist(   ref   msg[0]);

试试,有奇效
发表于:2007-01-30 13:49:1717楼 得分:0
以前遇到过,最后用unsafe解决。
发表于:2007-01-30 13:58:5418楼 得分:0
try
[structlayout(layoutkind.sequential   )]
public   class   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;
};
函数定义
[dllimport( "your.dll ",   charset=charset.ansi   )]
int   gsmparsemessagelist(intptr   pmsg);
发表于:2007-01-30 14:01:2419楼 得分:0
或者用unsafe自己修飾一下
发表于:2007-01-30 14:20:0220楼 得分:0
小弟在此谢过各位大哥了,尤其是hdt大哥,我刚试了,还是会出现 "未处理accessviolationexception,尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 ",看来只能用unsafe了,非常感谢各位
发表于:2007-01-30 15:25:1921楼 得分:0
试过我的方法没,我以前的问题就是这个方法解决的
使用一直正常
发表于:2007-01-30 16:30:1122楼 得分:0
kingdomgps大哥,你的方法我也试过了,的确好用,不过还是会出现这个问题,因为我要返回多个值,将结果返回到sm_param结构,所以不是因为我在gsmparsemessagelist中修改了sm_param结构引起这个错误?
发表于:2007-01-30 16:37:3123楼 得分:0
kingdomgps大哥,是不是我这里
sm_param   []   msg=new   sm_param   [10]   ;
gsmparsemessagelist(   ref   msg[0]);
有什么问题?
发表于:2007-01-31 10:15:5624楼 得分:0
牵强付会,用c++就用c++,用csharp就用csharp,互操作是微软向下兼容的策略,为什么不把时间放在上面
发表于:2007-01-31 10:50:3825楼 得分:0
mark!
发表于:2007-01-31 13:12:2326楼 得分:0
在你的结构体定义前面加上[structlayout(layoutkind.sequential   )]
然后再试试把你的数组改大一点传进去试试,有可能是数组越界哦
发表于:2007-01-31 16:35:0127楼 得分:0
只要你有钱,生活就多姿多彩,并且每人问你钱是怎么来的
日本松下有一位高官说过:即使我们不去拜靖国神社韩国人也不会买我们的产品,但不管我们再怎样的去拜靖国神社,中国人照样会买我们的产品。-----   一句让中国人从头凉到脚的话。   每直接或间接地购买100元日本货,你就:   1.为日本厂家增加40元的毛利收入   2.为日本企业增加了20元的扩张资本   3.为日本政府增加了5元的税收收入   4.给日本的所谓自慰队增加了   10颗子弹   5.多印6~8页的篡改历史的教科书和文件   6.送给小犬蠢一狼参拜鬼社的汽油费   **。如果你买日本汽车,将来开上中国街头的日本坦克就是你造的!!   **。如果你买日本橱具,将来射穿你儿子头颅的子弹就是你造的!!   **。如果你买日本电视音响,将来就会在战地喇叭中听到中国人被杀的哀鸣!!!我们没有时间和权力去采取政治行动,我们只能作力所能及的事,拒买日货是我们对付日本人的最好行动,不但简单而且有效.我每天上网必做的一件事就是把此这篇文章贴到可能的地方,只要上网,我至少要贴上10次!!!作为一个有良知的中国人,来和我和许多爱国人士一起并肩战斗吧!!   请把此文贴到一切可能的地方,你一定会为你的所作所为而自豪
发表于:2007-01-31 18:37:5628楼 得分:0
“未处理accessviolationexception,尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”这样的错误应该是数据保护。

最近也遇到过类似问题,不过是c++调用delphi的时候出现的。你尝试一下在c#内使用array.clear(test,0,65536);
先清零数据。
在c++中使用   void   *   作为形参,然后c++内所有操作使用   强制类型转换后的指针自增、自减操作来完成。不知道这样的方式是否可以解决你的问题。
发表于:2007-01-31 19:11:3029楼 得分:0
该回复于2007-12-21 20:26:50被管理员或版主删除
发表于:2007-02-01 09:01:5630楼 得分:0
多谢名位的帮助,还是上面那位兄弟说得对,以前为了兼容别人做的dll没办法,不过发现在c#这样调用太没效率,还是用c#自己重做吧.


快速检索

最新资讯
热门点击