У меня есть DLL, написанная на C++. Я хочу вызвать в нем функцию из Delphi 7.
У меня есть только пример, написанный на VB.NET.
Я попытался преобразовать код самостоятельно, прежде чем публиковать здесь.
Проблема в том, что когда я вызываю функцию, она выдает неверный вывод в двоичном формате, что, очевидно, означает, что я делаю что-то не так с вводом.
Вот исходный код в VB.NET:
Private Shared Declare Unicode Function Read_Write Lib "Subway.dll" (obej As IntPtr, Data_in As Byte(), in_siz As Integer, <Out()> ByRef Data_out As IntPtr, ByRef out_siz As Integer) As Integer
Dim obej As IntPtr = IntPtr.Zero
Dim Data_out As IntPtr = 0
Dim out_siz As Integer = 0
Dim Res As Integer = -1
Res = Read_Write(obej, Encoding.[Default].GetBytes(Mystr), Mystr.Length, Data_out, out_siz)
И мой конвертированный код в Delphi:
function Read_Write(obej: Pointer; Data_in: TByteDynArray; in_siz:Cardinal; var Data_out: TByteDynArray; var out_siz: Cardinal): Integer; stdcall; external 'Subway.dll';
var
tx, rx: TByteDynArray;
obej: pointer;
s:string;
Res: Integer;
out_siz: Integer;
SetLength(tx, Length(s));
Move(s[1], tx[0], Length(s));
Res := Read_Write(obej, tx, length(s), rx, out_siz);
Оригинальный вызов (язык C):
int __stdcall Read_Write(void *u_arg, const unsigned char *p_data_in, unsigned int data_in_len, unsigned char **pp_data_out, unsigned int *p_data_out_len);
Ваше объявление Delphi Read_Write()
не соответствует объявлению VB.NET. Вы не принимаете во внимание, как .NET упорядочивает параметры для неуправляемых языков. Кроме того, TByteDynArray
— это специфичный для Delphi тип, который вы не можете передать как есть в другие языки, особенно в выходных параметрах.
Вместо этого попробуйте что-то вроде этого:
function Read_Write(obej: Pointer; Data_in: PByte; in_siz: Integer, var Data_out: Pointer; var out_siz: Integer): Integer; stdcall; external 'Subway.dll';
var
obej: Pointer;
Data_out: Pointer;
out_siz: Integer;
Res: Integer;
MyStr: AnsiString;
buf: TByteDynArray;
begin
...
obej := nil;
Data_out := nil;
out_siz := 0;
MyStr := ...;
SetLength(buf, Length(MyStr));
Move(PAnsiChar(MyStr)^, PByte(buf)^, Length(MyStr));
Res := Read_Write(obej, PByte(buf), Length(buf), Data_out, out_siz);
// use Data_out up to out_siz bytes as needed...
// free Data_out as needed...
...
end;
Кроме того, вы можете опустить TByteDynArray
и просто вставить данные AnsiString
напрямую:
Res := Read_Write(obej, PByte(PAnsiChar(MyStr)), Length(MyStr), Data_out, out_siz);
@Maaz нет, потому что 1) Encoding
не существует в Delphi 7 и 2) AnsiString
уже находится в том же формате памяти, который возвращает Encoding.Default.GetBytes()
. Происходит что-то еще. У вас нет файла C/C++ .h
для DLL? Это было бы очень полезно для определения точного объявления, необходимого для функции. Чего именно вы ожидаете на выходе и что на самом деле получаете вместо этого? Пожалуйста, отредактируйте свой вопрос, чтобы показать это.
Хорошо, после некоторой помощи я нашел встроенную функцию dll .... int __stdcall Read_Write (void * u_arg, const unsigned char * p_data_in, unsigned int data_in_len, unsigned char ** pp_data_out, unsigned int * p_data_out_len); .... И о вывод, который я сравниваю, и он не совпадает с оригинальным, поэтому, скорее всего, мой метод вызова неверен, спасибо за ваше терпение;
@Maaz перевод этой декларации C в Delphi function Read_Write(u_arg: Pointer; const p_data_in: PByte; data_in_len: Cardinal; var pp_data_out: PByte; var p_data_out_len: Cardinal): Integer; stdcall;
, который почти идентичен исходной декларации, которую я вам дал. Выходные данные будут одинаковыми независимо от того, какое объявление вы используете. Вы еще не ответили на мой вопрос о том, как на самом деле выглядят выходные данные и как вы ожидаете, что они будут выглядеть.
Спасибо, я пробовал оба способа, к сожалению, я все еще получаю неправильный вывод, может быть, я игнорирую «Кодировку.[По умолчанию].GetBytes(Mystr)» ??