gpt4 book ai didi

c# - Pinvoke 调用总是返回 -1

转载 作者:太空宇宙 更新时间:2023-11-03 11:35:06 24 4
gpt4 key购买 nike

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);

handle 是 IntPtr 的调用:

handle = Unmanaged.SerialWrapper.OpenSerialConnection(portName,
baudRate,
parityToInt(parity),
dataBits,
stopBitsToInt(stopBits));

无论我在 OpenSerialConnection C++ 代码中有什么,handle 的值总是以 -1 返回,我已剥离该函数以仅返回 4 的 int 值作为测试。

我完全被难住了,我所有的阅读和搜索都证明对解决这个问题没有帮助。

有什么建议吗?

编辑以消除复制错误

解决方案:

我有一个双重错误。根据下面的建议,将返回值从 C++ 更改为 INT_PTR 以及平台更改,我能够获得返回有效句柄的调用。

非常感谢您的帮助:)

最佳答案

您的代码正在将 HANDLE 转换为 int。在 64 位平台上,这将导致截断和数据丢失,因为 HANDLE 是 64 位宽而 int 只有 32 位宽。编译器应该(至少)用警告标记它。

尝试从 OpenSerialConnection() 返回一个 INT_PTR(并相应地更改 C# 包装器的返回类型)。

关于c# - Pinvoke 调用总是返回 -1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6520891/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com