我正在使用标签阅读器,我能够连接它并读取一些数据.我的问题是当我尝试读取标签id时,这是一个很大的字符序列.SDK是用C语言编写的,我正在开发一个c#应用程序.short GetIDBuffer(HANDLE hCom, unsigned char* DataFla...
我正在使用标签阅读器,我能够连接它并读取一些数据.我的问题是当我尝试读取标签id时,这是一个很大的字符序列.
SDK是用C语言编写的,我正在开发一个c#应用程序.
short GetIDBuffer(HANDLE hCom, unsigned char* DataFlag, unsigned char * Count,
unsigned char *value, unsigned char* StationNum)
在我的C#应用??程序中:
[DllImport("Reader2.dll",CharSet = CharSet.Ansi)]
public static extern short GetIDBuffer(IntPtr hCom, ref uint DataFlag,
ref uint Count, ref String value, ref uint StationNum);
数据标记,计数,站号主要是小序列,其中uint类型表现良好.但是当谈到价值时,这是一个很大的序列.我尝试了类型字符串,但它抛出了这个异常:
Attempted to read or write protected memory. This is often an
indication that other memory is corrupt.
> [MarshalAs(UnmanagedType.LPWStr)]字符串值
没有解决问题
>计数值正确返回
>我的操作系统是64位:我使用corflags application.exe / 32bit,我能够正确加载DLL.
代码快照:
[DllImport("Reader2.dll")]
public static extern byte OpenReader(ref IntPtr hCom, byte LinkType, string com_port, uint port);
[DllImport("Reader2.dll")]
public static extern short GetIDBuffer(IntPtr hCom, ref byte DataFlag, ref byte Count,**(type)** value , ref byte StationNum);
static void Main(string[] args)
{
byte count = 0, station = 1, flag = 0;
IntPtr hcom = IntPtr.Zero;
OpenReader(ref hcom, 2, "192.168.0.178", 4001);
// valid handle returned from openReader
//
**GetIDBuffer code**
//
解决方法:
您不应该使用corflags application.exe / 32bit.您需要做的就是在project / properties / build中将平台目标设置为x86.
这将起作用(它使用我使用上面给出的相同签名创建的测试本机方法).
第一种方法不需要unsafe关键字,或者要求在“允许不安全代码”设置为true的情况下构建项目.
internal static class NativeMethods
{
[DllImport("Reader2.dll")]
public static extern short GetIDBuffer(
IntPtr hCom, ref byte dataFlag, ref byte count,
byte [] value, ref byte stationNum);
}
static int TestGetIDBuffer()
{
const int arraySize = 255;
byte[] bytes = new byte[arraySize + 1];
byte dataFlag = 0;
byte count = arraySize;
byte status = 0;
int retval = NativeMethods.GetIdBuffer(IntPtr.Zero, ref dataFlag, ref count, bytes, ref status);
Debug.WriteLine(Encoding.ASCII.GetString(bytes));
Debug.WriteLine(dataFlag);
Debug.WriteLine(status);
Debug.WriteLine(count);
Debug.WriteLine(retval);
return retval;
}
这是使用固定字节数组的替代方法.
第二种方法需要unsafe关键字,并且项目是使用“允许不安全代码”设置为true构建的.
internal static class NativeMethods
{
[DllImport("Reader2.dll")]
public static extern unsafe short GetIDBuffer(
IntPtr hCom, ref byte dataFlag, ref byte count,
byte* value, ref byte stationNum);
}
static unsafe int TestGetIDBuffer()
{
const int arraySize = 255;
byte[] bytes = new byte[arraySize + 1];
byte dataFlag = 0;
byte count = arraySize;
byte status = 0;
int retval;
fixed (byte* buffer = bytes)
retval = NativeMethods.GetIdBuffer(
IntPtr.Zero, ref dataFlag, ref count, buffer, ref status);
Debug.WriteLine(Encoding.ASCII.GetString(bytes));
Debug.WriteLine(dataFlag);
Debug.WriteLine(status);
Debug.WriteLine(count);
Debug.WriteLine(retval);
return retval;
}
dataFlag,count和stationNum似乎都是输入/输出字节值.
填充的数据缓冲区是一个字节数组.需要修复此缓冲区,以便在调用本机方法时GC不会移动它.这在第一个示例中隐式完成,在第二个示例中显式完成.
我假设可用的缓冲区大小应该传递给count参数中的方法,并且退出时的这个值将是使用的缓冲区数量.我允许一个额外的字节,以确保如果字节数组需要转换为字符串,则存在空终止字符.
实际上有两种形式的固定语句.在这个MSDN article中提到的一个允许你创建固定大小的数组,如
public fixed byte Bytes [ArraySize];
此MSDN article中的另一个允许您固定变量的位置以获取其地址.
这是我的C测试代码:
extern "C" __declspec(dllexport) unsigned short __stdcall GetIDBuffer(
HANDLE hCom, unsigned char * dataFlag, unsigned char * count,
unsigned char* buffer, unsigned char * status )
{
memset(buffer, 0x1E, *count);
*dataFlag = 0xa1;
*count = 0x13;
*status = 0xfe;
return 0x7531;
}
上面给出的C#代码与我的测试代码之间的唯一区别是,由于我使用了C编译器,因此必须以不同方式指定入口点,例如
[DllImport("PInvokeTestLib.dll", EntryPoint = "_GetIDBuffer@20")]
public static extern unsafe short GetIdBuffer(...
您可以安全地将传递给方法的参数(不包括值数组参数)指定为除byte之外的基本类型,例如int,long等.这是因为1)值在引用中传递,2)x86使用很少 – 字节序字节排序.这导致单个字节被写入传入的四字节int的最低有效字节.
建议使用匹配类型,在这种情况下为byte.
本文标题为:尝试在C#中传递大量字符时尝试读取或写入受保护的内存
- C# 使用Aspose.Cells 导出Excel的步骤及问题记录 2023-05-16
- c# 模拟线性回归的示例 2023-03-14
- user32.dll 函数说明小结 2022-12-26
- WPF使用DrawingContext实现绘制刻度条 2023-07-04
- 如何使用C# 捕获进程输出 2023-03-10
- 在C# 8中如何使用默认接口方法详解 2023-03-29
- Unity3D实现渐变颜色效果 2023-01-16
- Unity Shader实现模糊效果 2023-04-27
- .NET CORE DI 依赖注入 2023-09-27
- Oracle中for循环的使用方法 2023-07-04