函数原型:
/// <param name="pConvInfo">指向用来保存转换器列表的缓存</param>
/// <param name="count">为缓存中可保存多少个CONVINFO结构。</param>
/// <param name="bEnableMsg">在搜索的时候是否允许处理窗口消息。</param>
/// <param name="timeout">超时时间,单位为毫秒。</param>
/// <returns>搜索到的转换器的数目</returns>
int _stdcall FindConverter(CONVINFO *pConvInfo,int count,BOOL bEnableMsg,DWORD timeout);
c#函数申明:
[DllImport("Setting.dll",CharSet = CharSet.Ansi)]
internal unsafe static extern int FindConverter(_CONVINFO[] pConvInfo, int count, bool bEnableMsg, uint timeout);
[StructLayout(LayoutKind.Sequential)]
public struct _CONVINFO
{
public ushort devType;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public string strIP;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public string strMAC;
}
c#调用:
_CONVINFO[] Buffer = new _CONVINFO[256];
int ILen = FindConverter(Buffer, 256, true, 3000);
函数调用后,Buffer里面没有数据返回。怎么回事?
/// <param name="pConvInfo">指向用来保存转换器列表的缓存</param>
/// <param name="count">为缓存中可保存多少个CONVINFO结构。</param>
/// <param name="bEnableMsg">在搜索的时候是否允许处理窗口消息。</param>
/// <param name="timeout">超时时间,单位为毫秒。</param>
/// <returns>搜索到的转换器的数目</returns>
int _stdcall FindConverter(CONVINFO *pConvInfo,int count,BOOL bEnableMsg,DWORD timeout);
c#函数申明:
[DllImport("Setting.dll",CharSet = CharSet.Ansi)]
internal unsafe static extern int FindConverter(_CONVINFO[] pConvInfo, int count, bool bEnableMsg, uint timeout);
[StructLayout(LayoutKind.Sequential)]
public struct _CONVINFO
{
public ushort devType;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public string strIP;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public string strMAC;
}
c#调用:
_CONVINFO[] Buffer = new _CONVINFO[256];
int ILen = FindConverter(Buffer, 256, true, 3000);
函数调用后,Buffer里面没有数据返回。怎么回事?
解决方案 »
- c# 寻找字符串中指定 字段 替换
- do while(false) 怎么用不了continue?
- c# 读取文本内容问题
- 键盘口扫码枪 , 如何不用textbox? 在线等。
- 哭!FORM上的控件都不见了!
- 大师们,winform datagridview有没有一个属性能显示目前统计的条数?或者bindinnavigator
- 怎样做个软件升级?
- vs2003 和 vs2005 beta2 能共存吗?
- oracle同时读取clob字段和其他字段的sql语句问题
- [WinForm]如何在DataGrid中即时显示新增的数据记录??
- 如何在导出Excel时控制其单元格的颜色及样式?
- 有关SerialPort导致机器崩溃的问题!
可以为传递到非托管函数或从非托管函数返回的结构和类的字段指定自定义封送处理属性。通过向结构或类的字段中添加 MarshalAs属性可以做到这一点。还必须使用 StructLayout 属性设置结构的布局,还可以控制字符串成员的默认封送处理,并设置默认封装大小。
示例 3
本示例说明如何为结构指定自定义封送处理属性。
请考虑下面的 C 结构:
typedef struct tagLOGFONT
{
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
TCHAR lfFaceName[LF_FACESIZE];
} LOGFONT; 在 C# 中,可以使用 StructLayout 和 MarshalAs 属性描述前面的结构,如下所示:
// logfont.cs
// compile with: /target:module
using System;
using System.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential)]
public class LOGFONT
{
public const int LF_FACESIZE = 32;
public int lfHeight;
public int lfWidth;
public int lfEscapement;
public int lfOrientation;
public int lfWeight;
public byte lfItalic;
public byte lfUnderline;
public byte lfStrikeOut;
public byte lfCharSet;
public byte lfOutPrecision;
public byte lfClipPrecision;
public byte lfQuality;
public byte lfPitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=LF_FACESIZE)]
public string lfFaceName;
}
有关 StructLayout 属性的语法的更多信息,请参见 StructLayoutAttribute 类。
然后即可将该结构用在 C# 代码中,如下所示:// pinvoke.cs
// compile with: /addmodule:logfont.netmodule
using System;
using System.Runtime.InteropServices;
class PlatformInvokeTest
{
[DllImport("gdi32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr CreateFontIndirect(
[In, MarshalAs(UnmanagedType.LPStruct)]
LOGFONT lplf // characteristics
);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(
IntPtr handle
);
public static void Main()
{
LOGFONT lf = new LOGFONT();
lf.lfHeight = 9;
lf.lfFaceName = "Arial";
IntPtr handle = CreateFontIndirect(lf);
if (IntPtr.Zero == handle)
{
Console.WriteLine("Can't creates a logical font.");
}
else
{
if (IntPtr.Size == 4)
Console.WriteLine("{0:X}", handle.ToInt32());
else
Console.WriteLine("{0:X}", handle.ToInt64()); // Delete the logical font created.
if (!DeleteObject(handle))
Console.WriteLine("Can't delete the logical font");
}
}
}
运行示例
C30A0AE5
代码讨论
在前面的示例中,CreateFontIndirect 方法使用了一个 LOGFONT 类型的参数。MarshalAs 和 In 属性用于限定此参数。程序将由此方法返回的数值显示为十六进制大写字符串。
在C#里把_CONVINFO[] pConvInfo,改成int32 pConvInfo
因为函数其实是传的指针,这样pConvInfo里得到的是这个内存块的地址指针再用C#里的Marshal.Copy或是Marshal.PtrToStructure把这个指针指的内存所在的内容COPY到你的Buffer里去
/// <param name= "pConvInfo "> 指向用来保存转换器列表的缓存 </param>
/// <param name= "count "> 为缓存中可保存多少个CONVINFO结构。 </param>
/// <param name= "bEnableMsg "> 在搜索的时候是否允许处理窗口消息。 </param>
/// <param name= "timeout "> 超时时间,单位为毫秒。 </param>
/// <returns> 搜索到的转换器的数目 </returns>
int _stdcall FindConverter(CONVINFO *pConvInfo,int count,BOOL bEnableMsg,DWORD timeout);
c#函数申明:
[DllImport( "Setting.dll ",CharSet = CharSet.Ansi)]
internal unsafe static extern int FindConverter(_CONVINFO[] pConvInfo, int count, bool bEnableMsg, uint timeout);
[StructLayout(LayoutKind.Sequential)]
public struct _CONVINFO
{
public ushort devType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string strIP;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string strMAC;
}
c#调用:
_CONVINFO[] Buffer = new _CONVINFO[256];
int ILen = FindConverter(Buffer, 256, true, 3000);
函数调用后,Buffer里面没有数据返回。
public struct CONVINFO
{
MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public ushort devType;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public string strIP;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public string strMAC;
} CONVINFO con = new CONVINFO();
[DllImport("gdi32.dll"]
public static extern int FindConverter(ref con,int count,bool bEnableMsg,uint timeout);
最好把C++的结构贴出来。
c#调用:
_CONVINFO Buffer = new _CONVINFO();
int ILen = FindConverter(ref Buffer, 1, true, 3000);
原型改为:
[DllImport( "Setting.dll ",CharSet = CharSet.Ansi)]
internal unsafe static extern int FindConverter(ref _CONVINFO pConvInfo, int count, bool bEnableMsg, uint timeout); 能够返回,Buffer有值,但是需要返回多个值。
{
char strMAC[20];
char strIP[20];
WORD devType;
}CONVINFO;
LOVESONGFOREVER 谢谢,但只能返回一个值
internal unsafe static extern int FindConverter(ref _CONVINFO[] pConvInfo, int count, bool bEnableMsg, uint timeout);
int ILen = FindConverter(ref Buffer, 256, true, 3000);
试试看行不
public struct CONVINFO
{
MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public byte[] strMAC;
MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public byte[] strIP;
MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
int devType;
}
internal unsafe static extern int FindConverter(int32 pConvInfo, int count, bool bEnableMsg, uint timeout);
[StructLayout(LayoutKind.Sequential)]
public struct _CONVINFO
{
public ushort devType;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public string strIP;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
public string strMAC;
} int32 pBuffer;
int ILen = FindConverter(pBuffer, 256, true, 3000);
IntPtr pb = (IntPtr)pBuffer;
for (int i = 0; i < ILen; ++i)
{
//extract struct from pointer
_CONVINFO q = (_CONVINFO)Marshal.PtrToStructure(pb, typeof(_CONVINFO));
//让指针指到下一个,一直这样循环
pb = (IntPtr)(pb.ToInt32() + Marshal.SizeOf(typeof(_CONVINFO)));
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public string strIP;结构这样封装;
typedef struct _CONVSETTING
{
NETSETTING netSetting;
SOCKSETTING sockSetting[8];
COMSETTING comSetting[8];
}C#中申明怎么定义
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _CONVSETTING
{
public _NETSETTING netSetting;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public _SOCKSETTING[] sockSetting;
[MarshalAs(UnmanagedType.LPStruct, SizeConst = 8)]
public _COMSETTING[] comSetting;
}
调用时提示:
类型“PbcClass.NetModelMethod+_CONVSETTING”不能作为非托管结构进行封送处理;无法计算有意义的大小或偏移量。
C原型
typedef struct _CONVSETTING
{
NETSETTING netSetting;
SOCKSETTING sockSetting[8];
COMSETTING comSetting[8];
}C#中申明怎么定义
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _CONVSETTING
{
public _NETSETTING netSetting;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public _SOCKSETTING[] sockSetting;
[MarshalAs(UnmanagedType.LPStruct, SizeConst = 8)]
public _COMSETTING[] comSetting;
}这种类型怎么处理,解决马上送分.谢谢
http://topic.csdn.net/u/20090106/10/cd130dad-4d61-4bad-bb97-5d786fee9b26.html