Преобразование декларации 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';
Другие вопросы по тегам