各位高手好,问题如下:
struct HY_RECT_S
{
long lLeft;
long lRight;
long lTop;
long lBottom;
}; struct ID_CARD_S
{
char szText[10][256];
HY_RECT_S idRect[10];
};long __stdcall Get_IdcData(int iCardType, char* szFileNameIn, char *szFullFileNameOut, char *szHeadFileNameOut, ID_CARD_S* pstOut);我在C#中的定义如下:
[StructLayout(LayoutKind.Sequential)]
public struct HY_RECT_S
{
public Int32 lLeft;
public Int32 lRight;
public Int32 lTop;
public Int32 lBottom; public void Initialize()
{
lLeft = 0;
lRight = 0;
lTop = 0;
lBottom = 0;
}
} [StructLayout(LayoutKind.Sequential)]
public struct ID_CARD_S
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public string[] szText; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public HY_RECT_S[] idRect; public void Initialize()
{
//初始化数组大小
szText = new string[10];
idRect = new HY_RECT_S[10]; //初始化数组中每个元素的长度或值
for (int i = 0; i < szText.Length; i++)
{
//szText[i] = (new char[256]).ToString(); StringBuilder buffer = new StringBuilder(256); for (int j = 0; j < 256; j++)
{
buffer.Append((char)0);
}
//buffer.Append('*', buffer.Capacity - 1);
//buffer.Append((char)0, buffer.Capacity - 1);
szText[i] = buffer.ToString(); //buffer.Append('*', buffer.Capacity - 8);
} for (int i = 0; i < idRect.Length; i++)
{
idRect[i].Initialize();
}
}//初始化结束
}对DLL的声明如下:
[DllImport("Dll\\IDRCore.dll", EntryPoint = "Get_IdcData", CharSet = CharSet.Ansi)]
public static extern Int32 Get_IdcData(Int32 iCardType, [In] string szFileNameIn, [Out] string szFileNameOut, [Out] string szHeadFileNameOut, [In, Out] ref ID_CARD_S pstOut);调用:
IDRCore.ID_CARD_S sCard=new IDRCore.ID_CARD_S();
sCard.Initialize(); int iret;
iret=IDRCore.Get_IdcData(1, Application.StartupPath + "\\1.bmp",Application.StartupPath+ "\\2.bmp",Application.StartupPath+ "\\3.bmp", ref sCard);问题:
调用过程没有报错,但在关闭时系统报错,而且szText没有值,可能是内存问题,请问以上对结构的声明有问题吗?
看过微软PINVOKELIB.DLL的调用例子,但好象没有这么复杂的例子.
这个应用的难点是:1、使用了结构,2、结构中包括结构数组,3、结构中包括定长字符串数组,
请高人指点一下,不胜感激。
struct HY_RECT_S
{
long lLeft;
long lRight;
long lTop;
long lBottom;
}; struct ID_CARD_S
{
char szText[10][256];
HY_RECT_S idRect[10];
};long __stdcall Get_IdcData(int iCardType, char* szFileNameIn, char *szFullFileNameOut, char *szHeadFileNameOut, ID_CARD_S* pstOut);我在C#中的定义如下:
[StructLayout(LayoutKind.Sequential)]
public struct HY_RECT_S
{
public Int32 lLeft;
public Int32 lRight;
public Int32 lTop;
public Int32 lBottom; public void Initialize()
{
lLeft = 0;
lRight = 0;
lTop = 0;
lBottom = 0;
}
} [StructLayout(LayoutKind.Sequential)]
public struct ID_CARD_S
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public string[] szText; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public HY_RECT_S[] idRect; public void Initialize()
{
//初始化数组大小
szText = new string[10];
idRect = new HY_RECT_S[10]; //初始化数组中每个元素的长度或值
for (int i = 0; i < szText.Length; i++)
{
//szText[i] = (new char[256]).ToString(); StringBuilder buffer = new StringBuilder(256); for (int j = 0; j < 256; j++)
{
buffer.Append((char)0);
}
//buffer.Append('*', buffer.Capacity - 1);
//buffer.Append((char)0, buffer.Capacity - 1);
szText[i] = buffer.ToString(); //buffer.Append('*', buffer.Capacity - 8);
} for (int i = 0; i < idRect.Length; i++)
{
idRect[i].Initialize();
}
}//初始化结束
}对DLL的声明如下:
[DllImport("Dll\\IDRCore.dll", EntryPoint = "Get_IdcData", CharSet = CharSet.Ansi)]
public static extern Int32 Get_IdcData(Int32 iCardType, [In] string szFileNameIn, [Out] string szFileNameOut, [Out] string szHeadFileNameOut, [In, Out] ref ID_CARD_S pstOut);调用:
IDRCore.ID_CARD_S sCard=new IDRCore.ID_CARD_S();
sCard.Initialize(); int iret;
iret=IDRCore.Get_IdcData(1, Application.StartupPath + "\\1.bmp",Application.StartupPath+ "\\2.bmp",Application.StartupPath+ "\\3.bmp", ref sCard);问题:
调用过程没有报错,但在关闭时系统报错,而且szText没有值,可能是内存问题,请问以上对结构的声明有问题吗?
看过微软PINVOKELIB.DLL的调用例子,但好象没有这么复杂的例子.
这个应用的难点是:1、使用了结构,2、结构中包括结构数组,3、结构中包括定长字符串数组,
请高人指点一下,不胜感激。
public struct ID_CARD_S
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public string[] szText; //<----
...
Thie one has problem.
char szText[10][256]; means an array of continuous 2560 bytes,
however, in your C# definition, string[] szText are ten 'pointers' that point to
ten seperated strings.To overcome this problem,
Method 1: you can simply use byte array[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2560]
public byte[] szText;
After the result is returned, you then parse the byte array into strings.Method 2: you can provide a custom Marshaler.
You can google ICustomMarshaler. Or, I can provide you an example in case you are really interested in it.