C#调用VC的DLL参数是自定义类型指针的问题

ffb 2004-08-09 01:21:38
C++中的结构如下:
typedef struct commconf
{
short total;
short level;
unsigned short tcp_port;
short cli_num;
int BW;
int BL;
unsigned short cliport[CLINUM_MAX];
unsigned char cli[CLINUM_MAX][20];
} COMMCONF;
函数定义:
int (*F_InitVp)(COMMCONF *pConf);

我改写在C#的如下:
const int CLINUM_MAX =30;
public struct commconf
{
public short total;
public short level;
public ushort tcp_port;
public short cli_num;
public int BW ;
public int BL;
ushort [] cliport;
byte [,] cli;
public commconf(int intParam)
{
total=0;
level=0;
tcp_port=0;
cli_num=0;
BW=0;
BL=0;
cliport=new ushort[CLINUM_MAX];
cli=new byte[CLINUM_MAX,20];
}
};
函数定义:
[DllImport("vp.dll", EntryPoint="InitVp",CharSet=CharSet.None)]
public static extern int F_InitVp(out commconf pConf);

调用的时候就内存溢出了,请问对于这种自定义的类型参数,并且参数还要返回值(一般传递的是指针),应该怎么处理?
...全文
885 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
ffb 2004-08-11
  • 打赏
  • 举报
回复
用了临时的方法暂时解决了,可是实际上这个还是传不了,给大家分了
ffb 2004-08-10
  • 打赏
  • 举报
回复
结构中数组的声明如果这样修改的话:
//[MarshalAs(UnmanagedType.I2)]
[FieldOffset(16)]IntPtr [] cliport;
//[MarshalAs(UnmanagedType.I1)]
[FieldOffset(76)]IntPtr [,] cli;
错误是:
未处理的“System.Runtime.InteropServices.COMException”类型的异常出现在 TCenter.exe 中。

其他信息: 格式太旧或是类型库无效。

[MarshalAs(UnmanagedType.I2)]这个属性加不加好像是没有什么效果
(备注,此DLL的函数在VC中可以正确调用)
ffb 2004-08-10
  • 打赏
  • 举报
回复
我又做了这样的尝试:
const int CLINUM_MAX =30;

[StructLayout(LayoutKind.Explicit)]
public struct commconf
{
//[MarshalAs(UnmanagedType.I2)]
[FieldOffset(0)]public short total;
//[MarshalAs(UnmanagedType.I2)]
[FieldOffset(2)]public short level;
//[MarshalAs(UnmanagedType.I2)]
[FieldOffset(4)]public ushort tcp_port;
//[MarshalAs(UnmanagedType.I2)]
[FieldOffset(6)]public short cli_num;
//[MarshalAs(UnmanagedType.I4)]
[FieldOffset(8)]public int BW ;
//[MarshalAs(UnmanagedType.I4)]
[FieldOffset(12)]public int BL;
//[MarshalAs(UnmanagedType.I2)]
[FieldOffset(16)]ushort [] cliport;
//[MarshalAs(UnmanagedType.I1)]
[FieldOffset(76)]byte [,] cli;
public commconf(int intParam)
{
total=0;
level=0;
tcp_port=0;
cli_num=0;
BW=0;
BL=0;
cliport=new ushort[CLINUM_MAX];
cli=new byte[CLINUM_MAX,20];
}
};
还是同样的错误,用IntPtr也试验了,但是方法可能不对,MSDN也没有例子,只有一个概述
youngfox 2004-08-10
  • 打赏
  • 举报
回复
兄弟,好好研究一下msdn里面对IntPtr的解释吧,多维数组就可以解决了,多维数组在托管与非托管代码中的传递也只能用IntPtr这种类型了。其实IntPtr这种类型对应的正是非托管环境下的指针类型。
ffb 2004-08-09
  • 打赏
  • 举报
回复
好像是数组就是不行,我又改成这样了:
[DllImport("vp.dll", EntryPoint="InitVp",CharSet=CharSet.Auto)]
public static extern int F_InitVp(ref commconf pConf);

public struct commconf
{
[MarshalAs(UnmanagedType.I2)]
public short total;
[MarshalAs(UnmanagedType.I2)]
public short level;
[MarshalAs(UnmanagedType.I2)]
public ushort tcp_port;
[MarshalAs(UnmanagedType.I2)]
public short cli_num;
[MarshalAs(UnmanagedType.I4)]
public int BW ;
[MarshalAs(UnmanagedType.I4)]
public int BL;
[MarshalAs(UnmanagedType.I2)]
ushort [] cliport;
[MarshalAs(UnmanagedType.I1)]
byte [,] cli;
public commconf(int intParam)
{
total=0;
level=0;
tcp_port=0;
cli_num=0;
BW=0;
BL=0;
cliport=new ushort[CLINUM_MAX];
cli=new byte[CLINUM_MAX,20];
}
};

调用
if (F_InitVp(ref myCOMMCONF)<0)
出错:
未处理的“System.TypeLoadException”类型的异常出现在 TCenter.exe 中。

其他信息: 无法封送类型 commconf 的字段 cliport:该类型无法作为结构字段进行封送处理。
ffb 2004-08-09
  • 打赏
  • 举报
回复
谢谢,真是好文章啊,不过有一个问题,文章里说
如果是数组(只说了一维),这样写:
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]

我的结构里恰好是一个多维数组:
unsigned char cli[CLINUM_MAX][20];
文章里没有说怎么定义
youngfox 2004-08-09
  • 打赏
  • 举报
回复
对于指针类型的传递,应该使用IntPtr这种类型
例如:
Vc的引出函数对应C#的函数:
private IntPtr abc(IntPtr a, IntPtr b, int c, bool d, IntPtr e);
这个函数中返回值和函数的参数有几个都是指针类型的
对于结构体的定义,结构体内部的指针类型也需要用IntPtr类型
对于IntPtr和结构体类型的转换可以用Marshal中的许多方法。在此不罗列了。
需要using System.Runtime.InteropServices;
欢迎一起研究.net技术
我的Email:zhangjn@supermap.com
canoe_eyes 2004-08-09
  • 打赏
  • 举报
回复
http://www.chinabyte.net/20030102/1646672.shtml
ncucf 2004-08-09
  • 打赏
  • 举报
回复
你把那个结构体,改成一个类试试,因为类总是传递引用,就不用加上out 修饰符了!
这个应该可以满足你的要求,你试试看!
ffb 2004-08-09
  • 打赏
  • 举报
回复
我觉着主要还是类型的问题,C#是双字节的,类型可能不对应,但是不知道怎么解决
herony420 2004-08-09
  • 打赏
  • 举报
回复
建议使用非托管的方法,你可以去看看msdn上关于这种的描述
ffb 2004-08-09
  • 打赏
  • 举报
回复
去掉out的话出的是:
无法封送类型 commconf 的字段 cli:该类型无法作为结构字段进行封送处理。

加上out出的是
OutOfMemory
张海霖 2004-08-09
  • 打赏
  • 举报
回复
帮你顶!

110,544

社区成员

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

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

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