Доступ к функции C ++, объявленной без соглашения о вызовах, указанного в Delphi

1

Я пытаюсь использовать DLL, две функции которой:

__declspec(dllexport) LPCWSTR* MW_ListReaders(_ULONG Context, int* NumberOfReaders);

__declspec(dllexport) _ULONG MW_Connect(_ULONG Context, LPCWSTR ReaderName);

Для использования с Delphi и для функции MW_ListReaders я сделал следующее утверждение

function MW_ListReaders(Context : int64; var NumberOfReaders : integer) : PWideChar; stdcall;

Не знаю много на С++ и, кроме того, указатели, я потерян.

Как я могу использовать эти две функции в Delphi?

  • 1
    Они похожи на cdecl для меня
  • 0
    Что касается того, как вызывать функции, мы можем только догадываться. Вам нужно прочитать документы.
Показать ещё 3 комментария
Теги:

2 ответа

3

MW_ListReaders() объявлена неверно.

Соглашение о вызове по умолчанию в C/C++, если не указано __cdecl, - __cdecl, а не __stdcall.

MW_ListReaders() возвращает указатель на указатель на широкий символ (который будет PPWideChar в Delphi), но вы объявили его как возвращающий указатель на широкий символ (PWideChar).

ULONG - это 32-битное целое число без знака, а не 64-битное целое число со знаком.

Попробуйте это вместо этого:

function MW_ListReaders(Context: UInt32; var NumberOfReaders: Integer): PPWideChar; cdecl; external 'filename.dll';

function MW_Connect(Context: UInt32; const ReaderName: PWideChar): UInt32; cdecl; external 'filename.dll'

UInt32 был добавлен в Delphi 2009. Если вы используете более старую версию или просто для хорошей практики в целом, вы можете (и должны) использовать тип ULONG или ULONG32 (и другие типы), который находится в блоке Windows вместо этого, чтобы поддерживать совместимость с оригинальными декларациями C/C++:

uses
  ..., Windows;

type
  PLPCWSTR = ^LPCWSTR;

function MW_ListReaders(Context: ULONG; var NumberOfReaders: Integer): PLPCWSTR; cdecl; external 'filename.dll';

function MW_Connect(Context: ULONG; ReaderName: LPCWSTR): ULONG; cdecl; external 'filename.dll'
  • 1
    Если возможно, я бы использовал оригинальные имена типов (например, ULONG , LPCWSTR ). Если они присутствуют в одном из модулей Winapi, они определены правильно, и нет необходимости думать, правильна ли ваша конверсия (например, PChar или PWideChar или что-то еще). Это позволяет избежать ошибок.
  • 0
    @RudyVelthuis: достаточно верно. С другой стороны, в Delphi для LPCWSTR* не существует существующего типа, поэтому вам придется определить его вручную: type PLPCWSTR = ^LPCWSTR; Я обновил свой ответ.
2

Я думаю, что _ULONG соответствует 32-разрядному беззнаковому целочисленному типу (по крайней мере, для компиляторов MS).
И обратите внимание, используя P PWideChar в качестве типа результата.

Изменение: вызов конвенции был изменен на cdecl, по умолчанию один, как заметил Дэвид Хеффернан.

function MW_ListReaders(Context: Cardinal; var NumberOfReaders : integer): PPWideChar; cdecl;
function MW_Connect(Context: Cardinal; ReaderName: PWideChar): Cardinal; cdecl;
  • 1
    Вы пропустили соглашение о вызовах по второй функции. Но это cdecl в соответствии с кодом в Q.
  • 0
    Да, вы правы, я слепо вставили stdcall от вопроса.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню