Visual Studio 2005 .NET SDK 2.0
我们需要包装旧的C ++函数来打开内部和外部端口的句柄(C#方法对我们的处理器来说有太多的开销)
这是原始的C ++函数:
extern "C" SERIALLIB_API HANDLE
OpenSerialConnection(TCHAR *port, int baudRate, int parity, int dataBits, int stopBits)
{
// Open the serial device file driver
HANDLE hSerial = CreateFile(port,
GENERIC_READ | GENERIC_WRITE,
0, // must be opened with exclusive-access
NULL, // default security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0, // overlapped I/O not supported
NULL // hTemplate must be NULL for comm devices
);
RETAILMSG(1, (TEXT("Handle %d\n"),hSerial));
// Ensure the handle opened correctly
if (hSerial == INVALID_HANDLE_VALUE)
{
RETAILMSG(1, (TEXT("INVALID HANDLE #1\n")));
return INVALID_HANDLE_VALUE;
}
// Set the handle to report only when there's
// a character to receive or when the transmit
// buffer is empty
if (!SetCommMask(hSerial, EV_RXCHAR|EV_TXEMPTY))
{
CloseHandle(hSerial);
RETAILMSG(1, (TEXT("INVALID HANDLE #2\n")));
return INVALID_HANDLE_VALUE;
}
// The handle will now be configured to be the requested
// serial interface. The current settings are retrieved,
// and only the necessary settings are changed.
DCB dcb;
ZeroMemory(&dcb, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
BOOL fSuccess = GetCommState(hSerial, &dcb);
if (!fSuccess)
{
CloseHandle(hSerial);
RETAILMSG(1, (TEXT("INVALID HANDLE #3\n")));
return INVALID_HANDLE_VALUE;
}
// Fill in DCB with the desired settings
dcb.BaudRate = baudRate; // set the baud rate
dcb.ByteSize = 8; // data size, xmit, and rcv
dcb.Parity = parity; // no parity bit
dcb.StopBits = stopBits; // one stop bit
// Set the timeout values to make reading a synchronous activity.
// Reading from the serial line takes place in a separate thread,
// so this is what we want.
COMMTIMEOUTS timeout;
timeout.ReadIntervalTimeout = MAXDWORD;
timeout.ReadTotalTimeoutConstant = MAXDWORD - 1;
timeout.ReadTotalTimeoutMultiplier = MAXDWORD;
timeout.WriteTotalTimeoutConstant = 0;
timeout.WriteTotalTimeoutMultiplier = 0;
if (!SetCommTimeouts(hSerial, &timeout) ||
!SetCommState(hSerial, &dcb))
{
CloseHandle(hSerial);
RETAILMSG(1, (TEXT("INVALID HANDLE #4\n")));
return INVALID_HANDLE_VALUE;
}
return hSerial;
}
C#包装器:
[DllImport("SerialLib.dll")]
public static extern IntPtr OpenSerialConnection(string port, int baudRate, int parity, int dataBits, int stopBits);
句柄是IntPtr的调用:
handle = Unmanaged.SerialWrapper.OpenSerialConnection(portName,
baudRate,
parityToInt(parity),
dataBits,
stopBitsToInt(stopBits));
无论我在OpenSerialConnection C ++代码中有什么,handle的值总是以-1返回,我已经将函数剥离为只返回一个4的int值作为测试。
我完全难过,所有的阅读和搜索都没有证明对解决这个问题有帮助。
有什么建议吗?
已编辑以删除复制错误
解决方案:
我发生了两次错误。根据下面的建议将返回值从C ++更改为INT_PTR并进行平台更改,我能够调用返回有效句柄。
非常感谢您的所有帮助:)
答案 0 :(得分:2)
您的代码正在将HANDLE
转换为int
。在64位平台上,这将导致截断和数据丢失,因为HANDLE
是64位宽,但int
只有32位宽。编译器应该用(至少)警告标记它。
尝试从INT_PTR
返回OpenSerialConnection()
(并相应地更改C#包装器的返回类型)。