Преобразование декларации C в Delphi XE2
У меня возникают проблемы при переводе некоторых объявлений C в Delphi XE2 для вызова функций в DLL. Я перевел все объявления функций из исходного файла Visual Basic, но при тестировании их я столкнулся с проблемами. Некоторые функции возвращали значения Long, но при отладке моего кода я заметил, что задействованные функции возвращали неверные значения. Затем я обратился к исходному коду на C, и там я нашел корень моих проблем: В какой-то момент в исходном коде C есть это объявление:
typedef struct { } __RSI_CHANNEL;
typedef __RSI_CHANNEL FAR* RSI_CHANNEL;
Теперь некоторые функции возвращают RSI_CHANNEL; эти функции возвращают значения следующим образом:
return (RSI_CHANNEL)ws;
И WS объявлен как:
rsiChannel FAR* ws = new FAR rsiChannel;
rsiChannel является структурой typedef. Пока все хорошо... я полагаю, что некоторые из вас уже определили это как PIMPL. Хорошо, в соответствии с комментариями к исходному коду, мне нужно сохранить это возвращаемое значение (RSI_CHANNEL) и проверить его на NULL, а также передать его через вызовы функций нетронутыми... ничего более... так что я считаю, что это должно быть реализовано в Delphi как указатель Но это не работает. Что-то вроде этого:
Type
RSI_CHANNEL = Pointer;
...{ later in implementation block }...
Function rsiInitWsock(HostName : PAnsiChar; port : Long) : RSI_CHANNEL; stdcall; external 'rsidll32';
Нет ошибок компиляции, нет ошибок во время выполнения. Если я вызываю эту функцию, я получаю ноль.
¿Есть идеи, как это можно реализовать в Delphi XE2? и что я делаю не так? заранее спасибо.
Дополнительные детали:
- Delphi XE2 (цель: Win32)
- Windows 7 x64
Я нашел проблему; это не имело отношения к моему коду, это было правильно с самого начала; это связано с функцией ping в DLL, она работает на ноутбуке, но не хочет работать с настольным ПК (оба Win7), а когда она не работает, она прерывает последующие вызовы функций в DLL (почему, я не знаю... пока). В любом случае, это не было полным решением, но @DavidHeffernan первым предложил идею, что проблема была в другом месте, поэтому я принимаю его ответ, главным образом потому, что он указал мне верное направление. Спасибо всем!
2 ответа
Как описано, ваша обработка RSI_CHANNEL
верно. Объявив это как Pointer
это соответствующее действие. Чтобы повысить безопасность типов, вы можете определить отдельный тип, а не псевдоним:
Type
RSI_CHANNEL = type Pointer;
Если port
параметр действительно WORD
тогда это отображается на Word
в Дельфи.
Что касается вашей проблемы, она лежит в другом месте. Перевод RSI_CHANNEL
это точно.
Поскольку RSI_CHANNEL
является типизированным указателем в коде C, я бы объявил аналогичный типизированный указатель в Delphi для сопоставления вместо использования нетипизированного Pointer
(это также соответствует современным версиям Delphi, использующим STRICT
чтобы избежать нетипизированных указателей в типах дескрипторов Win32 API, таких как HWND
, так далее):
type
RSI_CHANNEL = ^__RSI_CHANNEL;
__RSI_CHANNEL = record
end;
Function rsiInitWsock(HostName : PAnsiChar; port : WORD) : RSI_CHANNEL; stdcall; external 'rsidll32';