Отправка строки Delphi в качестве параметра в DLL - PullRequest
5 голосов
/ 23 июля 2010

Я хочу вызвать функцию DLL в Delphi 2010. Эта функция берет строку и записывает ее на принтер с интерфейсом USB. Я не знаю, на каком языке разработана DLL. Согласно документации, синтаксис функции:

int WriteUSB(PBYTE pBuffer, DWORD nNumberOfBytesToWrite);

Как мне объявить и использовать мою функцию в Delphi?

Я объявляю функцию следующим образом:

var
function WriteUSB(myP:pByte;n:DWORD): integer ; external 'my.dll';

Должен ли я использовать stdcall или cdecl в декларации?

Я вызываю функцию DLL следующим образом:

procedure myProc;
var 
   str : string:
begin
     str := 'AAAAAAAAAAAAAAAAAAAAA';
     WriteUSB(str,DWORD(length(tmp)));
end;

Но этот код постоянно дает мне исключение. Я знаю, что проблема в том, что String это Unicode и каждый символ> 1 байт. Я пытался преобразовать в различные типы строк (AnsiChar и ShortString), но мне не удалось.

Как правильно это сделать?

Ответы [ 4 ]

12 голосов
/ 23 июля 2010

Пара вещей.Прежде всего, если это интерфейс C, который выглядит так, как он есть, то вам нужно объявить импорт следующим образом:

function WriteUSB(myP:pAnsiChar; n:DWORD): integer; cdecl; external 'my.dll';

Затем, чтобы вызвать функцию, вам нужно использовать строку Ansi,и преобразовать его в PAnsiChar, например, так:

procedure myProc;
var 
   str : AnsiString;
begin
     str := 'AAAAAAAAAAAAAAAAAAAAA';
     WriteUSB(PAnsiChar(str), length(str));
end;

(приведение к DWORD не нужно.) Если вы сделаете это так, оно должно работать без проблем.

3 голосов
/ 23 июля 2010

Вы можете преобразовать строку в AnsiString (как уже упоминалось), если вы собираетесь использовать только символы Ansi, но если вы хотите использовать строки в юникоде, а DLL / принтер их примет, вы можете попробовать что-то вроде (не проверено, но я думаю, что это, как правило, корректно):

procedure myProc;
var
  str: string;
  buff: TBytes;
begin
  str := 'blahblahblah'; // plus additional unicode stuff
  buff := TEncoding.Default.GetBytes(str); // of TEncoding.UTF8 or... etc
  WriteUSB(@buff[0], Length(buff));
end;

Не знаю, будет ли это работать с этой конкретной DLL, но это более общий способ справиться с переходом на строки Unicode, а не предполагать,(и приведение к) AnsiString везде.

1 голос
/ 25 июля 2010

Большое спасибо за все отзывы. Я заставляю это работать, комбинируя ваши отзывы. Решение:

Декларация (я добавляю cdecl):

function WriteUSB( pc:pByte;n:DWORD): integer ; cdecl; external 'my.dll';

И звонок:

Procedure myProc;
Var
    str : string;
    buff : TBytes;
begin
    str := 'My string";
    buff := TEncoding.Default.GetBytes(str); // of TEncoding.UTF8 or... etc
            WriteUSB(pByte(@buff[0]), Length(buff))

...
End;

У меня есть некоторые проблемы со шведскими символами, но я их решу. Теперь я знаю, что вызов DLL правильный.

Еще раз спасибо за все отзывы. Это отличный форум.

BR Delphi User

1 голос
/ 23 июля 2010

Попробуйте сыграть его с pchar в вашем вызове:

  WriteUSB(pchar(str),DWORD(length(tmp))); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...