Привет, мне нужна помощь, чтобы понять, что эквивалентно С ++ Handle в C#. мне нужно вызвать эту dll, и предоставленный метод использует С ++, как показано ниже
HANDLE hCTAPI;
hCTAPI = ctOpen(NULL, NULL, NULL, 0);
if (hCTAPI == NULL)
dwStatus = GetLastError(); // get error
else {
ctTagWrite(hCTAPI, "SP123", "1.23");
ctClose(hCTAPI);
}
// example of open for remote TCP/IP connection.
hCTAPI = ctOpen("203.19.130.2", "ENGINEER", "user", 0);
в моем коде C#:
[DllImport(@"C:\Users\Admin\source\repos\WindowsFormsApp2\WindowsFormsApp2\dll\CtApi.dll")]
private static extern IntPtr ctOpen(string a, string b, string c, int d);
private void button1_Click(object sender, EventArgs e)
{
IntPtr ptrObj = Marshal.AllocHGlobal(4);
ptrObj = ctOpen("192.168.1.192", "Engineer", "00", 0);
}
API должен что-то возвращать. Когда я выполняю отладку, значение ptrObj всегда равно 0
Справочник по API
ctOpen(sComputer, sUser, sPassword, nMode)
HANDLE обычно переведено для IntPtr (или HandleRef, но это то же самое), поэтому ваш код может быть IntPtr ptrObj = ctOpen("192.168.1.192", "Engineer", "00", 0);. Но я не уверен, какой формат строки он ожидает. Попробуйте изменить свою декларацию в [DllImport(@"C:\Users\Admin\source\repos\WindowsFormsApp2\WindowsFormsApp2\dll\CtApi.dll", SetLastError = true, CharSet = CharSet.Auto)]. Если работает, попробуйте CharSet = CharSet.Ansi.
@Jimi не забудьте учесть CallingConvention и в DllImport. Не все API используют stdcall. Проверьте объявление ctOpen() на C++, чтобы узнать его истинное соглашение о вызовах.
@Remy Lebeau Если я правильно понял библиотеку, там указано Для использования 2015 CTAPI (...) пользователю необходимо установить распространяемый компонент Microsoft Visual C++ 2012 (x86) и .NET Framework 4.5.1.. Так что я предположил, что это довольно стандартно.
Спасибо вам, ребята. Решил проблему, обнаружил, что на сайте scada не включен API. протестирован с моим исходным кодом C#, и я также кодирую с помощью С ++, и оба работают
@Jimi, эта цитата не меняет того, что я сказал





HANDLE - это целое число без знака, представляющее указатель на ресурс.
uint hCTAPI = ctOpen(NULL, NULL, NULL, 0);
Должен работать на вас. Он дает вам указатель на ресурс, который вы создаете в своем случае. Когда вы хотите вызвать методы этого ресурса, методы, вероятно, потребуют, чтобы hCTAPI был первым (или последним) аргументом в подписи.
Нет, это не так, дескриптор - это указатель, который абсолютно не является «целым числом без знака».
@bindy: указатель, как определено стандартом C, может быть целым числом со знаком или без знака. согласно ISO; ISO / IEC 9899: 201x 6.5 Выражения, p7: Сохраненное значение объекта должно быть доступно только с помощью выражения lvalue, которое имеет один из следующих типов: 88) - тип, который является типом со знаком или без знака, соответствующим действующему типу объект, - тип, который является типом со знаком или без знака, соответствующим квалифицированной версии действующего типа объекта,
И в подтверждение этого взгляните на: docs.microsoft.com/en-us/dotnet/csharp/programming-guide/… Положите очки обратно ....
Вы цитируете правильную часть, но ничего не понимаете в том, что печатаете. Позвольте мне сказать это еще раз короткими словами: указатель не uint.
Я предполагаю, что целевая машина отклонила ваше соединение.
Попробуйте функцию GetLastError, чтобы проверить ошибку.
Попробуйте использовать Process Monitor, чтобы узнать, к чему пытается подключиться ваше приложение. Отфильтруйте по имени вашего процесса, а затем следите за событиями TCP *, вы должны увидеть IP-адрес и порт назначения.
P / S: Насколько я могу судить из документации CTAPI, подписи PInvoke, которые вы используете, верны, поэтому это может быть проблемой с вашей установкой / конфигурацией CT.
c++не встроен в типHANDLE, вам следует проверить спецификацию библиотеки.