Вызов функции C++ DLL в Delphi 7

У меня есть 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);
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
312
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваше объявление 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);

Спасибо, я пробовал оба способа, к сожалению, я все еще получаю неправильный вывод, может быть, я игнорирую «Кодировку.[По умолчанию].GetBytes(Mystr)» ??

Maaz 28.05.2019 00:04

@Maaz нет, потому что 1) Encoding не существует в Delphi 7 и 2) AnsiString уже находится в том же формате памяти, который возвращает Encoding.Default.GetBytes(). Происходит что-то еще. У вас нет файла C/C++ .h для DLL? Это было бы очень полезно для определения точного объявления, необходимого для функции. Чего именно вы ожидаете на выходе и что на самом деле получаете вместо этого? Пожалуйста, отредактируйте свой вопрос, чтобы показать это.

Remy Lebeau 28.05.2019 02:19

Хорошо, после некоторой помощи я нашел встроенную функцию 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 28.05.2019 03:05

@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;, который почти идентичен исходной декларации, которую я вам дал. Выходные данные будут одинаковыми независимо от того, какое объявление вы используете. Вы еще не ответили на мой вопрос о том, как на самом деле выглядят выходные данные и как вы ожидаете, что они будут выглядеть.

Remy Lebeau 28.05.2019 05:50

Другие вопросы по теме