Sending a Delphi string as a parameter to a DLL

I want to call a DLL function in Delphi 2010. This function takes a string and writes it to a USB printer. I do not know what language the DLL is developed. According to the documentation, the syntax of the function:

int WriteUSB(PBYTE pBuffer, DWORD nNumberOfBytesToWrite); 

How can I declare and use my function in Delphi?

I declare the function as follows:

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

Should I use stdcall or cdecl in the declaration?

I call the DLL function as follows:

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

But this code gives me an exception all the time. I know that the problem is that String is Unicode and each character> 1 byte. I tried converting to different types of strings ( AnsiChar and ShortString ), but I failed.

What is the right way to do this?

+4
source share
4 answers

Few things. First of all, if it is a C-interface that looks like this, then you need to declare the import as follows:

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

Then, to call the function, you need to use the Ansi string and convert it to PAnsiChar, for example:

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

(A cast to DWORD is optional.) If you do it this way, it should work without any problems.

+11
source

You can convert the string to AnsiString (as already mentioned) if you intend to use only Ansi characters, but if you want to use Unicode strings. And that the DLL / printer will accept them, you can try something line by line (untested, but I think it usually matches):

 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; 

I don’t know if this will work with this particular DLL, but this is a more general way to deal with the shift in Unicode strings, instead of accepting (and discarding) AnsiString everywhere.

+3
source

Try it with pchar in your call:

  WriteUSB(pchar(str),DWORD(length(tmp))); 
+1
source

Thanks so much for all the feedback. I make it work by combining your reviews. Decision:

Declaration (I add cdecl):

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

And the call:

 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; 

I have some problems with the Swedish characters, but I will solve it. Now I know that the DLL call is correct.

Thanks again for the feedback. This is a great forum.

BR User Delphi

+1
source

Source: https://habr.com/ru/post/1316614/


All Articles