powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Конвертация типов для работы с DLL C++ из Delphi
23 сообщений из 23, страница 1 из 1
Конвертация типов для работы с DLL C++ из Delphi
    #40130063
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Имеется DLL, написанная на C++, среди методов в заголовке (.h файл) есть функция (stdcall)

int (const char* name, const char* surname, const char* patronymic)

Как я понимаю, на Delphi функция будет выглядеть следующим образом:

function (name: PAnsiChar; surname: PAnsiChar; patronymic: PAnsiChar): integer; stdcall;


И действительно, до поры до времени всё работало, пока разработчик DLL не поменял заголовок своей DLL и не сделал

int (const char *name, const char *surname, const char *patronymic)

Теперь если с ней работать по-прежнему, фамилия имя и отчество передаются в DLL с искажениями.


Вопрос - как должна теперь выглядеть функция в DLL - чтобы она соответствовала новому объявлению функции в Delphi. Перерыла весь Интернет, пробовала и по-старому и

function (const name: PAnsiChar; const surname: PAnsiChar; const patronymic: PAnsiChar): integer; stdcall;
function (var name: PAnsiChar; var surname: PAnsiChar; var patronymic: PAnsiChar): integer; stdcall;

ничего не работает ...
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130067
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Код: plaintext
1.
int(const char* name, const char* surname, const char* patronymic)


Код: plaintext
1.
int(const char *name, const char *surname, const char *patronymic)



Разница между этими объявлениями чисто косметическая, работать оно перестало
совсем по другим причинам.

Зная Вас - это из-за обращения к уже освобождённой памяти.

Дуракам иногда внезапно перестаёт везти.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130079
zedxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Будет ошибка, если функция теперь не stdcall. Попробуйте cdecl или fastcall.

Calling Conventions Demystified
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130083
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Наталья87

Код: plaintext
1.
int (const char* name, const char* surname, const char* patronymic)


Код: plaintext
1.
int (const char *name, const char *surname, const char *patronymic)



Что-то я не увидел разницы...
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130104
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zedxxx
Попробуйте cdecl
Тогда при выходе из функции полезли бы артефакты на стеке. А сама функция отлично бы отработала. Был у меня когда-то такой опыт, когда я ошибочно вызывал cdecl функцию как stdcall. Тогда у меня все артефакты убирались вот такой конструкцией
Код: pascal
1.
2.
3.
4.
5.
6.
try
  func(...);
except
  on E: Exception do
    raise;
end;
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130155
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Понятно, спасибо. Будем разбираться с разработчиком DLL. Возможно, он косячит, а не я ...
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130358
shalamyansky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87

фамилия имя и отчество передаются в DLL с искажениями

Это настораживает. С искажениями - это как, "Наталья" превратилась в "Володю"?

Еще настораживают ваши PAnsiChar. Как вы их получаете? Если вот так

Код: pascal
1.
2.
3.
4.
5.
6.
var
    Name : STRING; //=UnicodeString;

    Name := 'Наталья';

    func( PAnsiChar( Name ), ... );


то у вас проблемы.
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130376
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
пробовала и по-старому и

function (const name: PAnsiChar; const surname: PAnsiChar; const patronymic: PAnsiChar): integer; stdcall;
function (var name: PAnsiChar; var surname: PAnsiChar; var patronymic: PAnsiChar): integer; stdcall;

ничего не работает ...
const в Си и в Паскале - совершенно разные вещи.
В Си это просто говорит компилятору, чтобы он запретил менять параметр в теле функции.
В Паскале же, кроме этого, происходит дополнительная передача параметра по ссылке
const p: PAnsiChar - это то же самое, что p: PP AnsiChar (ну и еще p менять нельзя). Короче, тот же var, только еще и говорит компилятору, чтобы запретил менять параметр в теле функции.

Пробовать же var - это всё равно, что пробовать double вместо string, результат будет такой же.
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130378
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockПробовать же var - это всё равно, что пробовать double вместо string, результат
будет такой же.

Адептов школы стохастического программирования это никогда не останавливало.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130388
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
В Паскале же, кроме этого, происходит дополнительная передача параметра по ссылке
Чушь!
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure Test(A: PChar; const B: PChar; var C: PChar); stdcall;
begin

end;

procedure TForm1.Button1Click(Sender: TObject);
var
  LStr: string;
  LArg: PChar;
begin
  LStr := 'ABC';
  LArg := PChar(LArg);
  Test(LArg, LArg, LArg);
end;


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Unit1.pas.542: Test(LArg, LArg, LArg);
008F893E 8D45F4            lea  eax,[ebp-$0c]
008F8941 50               push eax
008F8942 8B45F4           mov eax,[ebp-$0c]
008F8945 50               push eax
008F8946 8B45F4           mov eax,[ebp-$0c]
008F8949 50               push eax
008F894A E8B5FFFFFF       call Test
последний параметр честно ушел по ссылке, а первый и второй передался как есть. const в Паскале нужен, чтобы не копировать сложные типы, а передавать как есть
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130399
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87

...
И действительно, до поры до времени всё работало, пока разработчик DLL не поменял заголовок своей DLL и не сделал

int (const char *name, const char *surname, const char *patronymic)

Теперь если с ней работать по-прежнему, фамилия имя и отчество передаются в DLL с искажениями .


Очень интересно.
То есть, получается, функция вызывается, но доходят кракозябры вместо некоторых (или всех) букв?

Может, теперь DLL ожидает UTF8 или чего-то подобного?
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130409
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кроик Семён
функция вызывается, но доходят

Мне кажется, что если бы ТС знал, что там "доходит", его бы тут не было. :)
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130410
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
YuRock
В Паскале же, кроме этого, происходит дополнительная передача параметра по ссылке
Чушь!
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure Test(A: PChar; const B: PChar; var C: PChar); stdcall;
begin

end;

procedure TForm1.Button1Click(Sender: TObject);
var
  LStr: string;
  LArg: PChar;
begin
  LStr := 'ABC';
  LArg := PChar(LArg);
  Test(LArg, LArg, LArg);
end;



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Unit1.pas.542: Test(LArg, LArg, LArg);
008F893E 8D45F4            lea  eax,[ebp-$0c]
008F8941 50               push eax
008F8942 8B45F4           mov eax,[ebp-$0c]
008F8945 50               push eax
008F8946 8B45F4           mov eax,[ebp-$0c]
008F8949 50               push eax
008F894A E8B5FFFFFF       call Test
последний параметр честно ушел по ссылке, а первый и второй передался как есть. const в Паскале нужен, чтобы не копировать сложные типы, а передавать как есть

Честно говоря, даже не знал. Знал, что структуры по ссылке передаются при const, но думал, что и все типы так.
А теперь проветил, и оказывается, что даже структуры не все, а только те, что длиннее размера указателя.
Вот спасибо, век живи - век учись.
Интересно, в Си тоже так, или нет. Я уже и в этом не уверен, и проверить не на чем.
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130412
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockИнтересно, в Си тоже так, или нет.

У Си собственные методы оптимизации вызовов и они тоже в стиле "тут играем, а
тут рыбу заворачивали".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130415
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRock
Интересно, в Си тоже так, или нет.

Именно в С параметры всегда передаются копированием. Если нужно работать с оригиналом, то в функцию явно передается указатель - но тоже копированием.
В C++ есть ещё параметры - ссылки, это сахарок над указателями, типа паскалевских модификаторов var, out или const.
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130418
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Знал, что структуры по ссылке передаются при const,
Если соглашение вызова register, то все длинные структуры передаются по ссылке. А потом в функции параметры без const копируются в локальные переменные. А вот при stdcall структура без const помещается в стек целиком
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130421
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Если соглашение вызова register, то все длинные структуры передаются по ссылке. А потом в функции параметры без const копируются в локальные переменные. А вот при stdcall структура без const помещается в стек целиком
Не может быть, сейчас проверил.
Без const - всегда по значению передаются, с const - всегда по ссылке.
Что при register, что при stdcall, что при pascal, что при cdecl.
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130428
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Не может быть, сейчас проверил.
Без const - всегда по значению передаются
Издеваешься?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
procedure TestSmReg(A: TSmallPoint; const B: TSmallPoint; var C: TSmallPoint; D: TSmallPoint);
begin

end;

procedure TestSmStd(A: TSmallPoint; const B: TSmallPoint; var C: TSmallPoint; D: TSmallPoint); stdcall;
begin

end;

procedure TestLongReg(A: TRect; const B: TRect; var C: TRect; D: TRect);
begin

end;

procedure TestLongStd(A: TRect; const B: TRect; var C: TRect; D: TRect); stdcall;
begin

end;

procedure TForm1.Button1Click(Sender: TObject);
var
  LArgSm: TSmallPoint;
  LArgLong: TRect;
begin
  TestSmReg(LArgSm, LArgSm, LArgSm, LArgSm);
  TestSmStd(LArgSm, LArgSm, LArgSm, LArgSm);
  TestLongReg(LArgLong, LArgLong, LArgLong, LArgLong);
  TestLongStd(LArgLong, LArgLong, LArgLong, LArgLong);
end;

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
Unit1.pas.555: TestSmReg(LArgSm, LArgSm, LArgSm, LArgSm);
008F8964 8B45F8           mov eax,[ebp-$08]
008F8967 50               push eax
008F8968 8D4DF8           lea ecx,[ebp-$08]
008F896B 8B55F8           mov edx,[ebp-$08]
008F896E 8B45F8           mov eax,[ebp-$08]
008F8971 E88EFFFFFF       call TestSmReg
Unit1.pas.556: TestSmStd(LArgSm, LArgSm, LArgSm, LArgSm);
008F8976 FF75F8           push dword ptr [ebp-$08]
008F8979 8D45F8           lea eax,[ebp-$08]
008F897C 50               push eax
008F897D FF75F8           push dword ptr [ebp-$08]
008F8980 FF75F8           push dword ptr [ebp-$08]
008F8983 E894FFFFFF       call TestSmStd
Unit1.pas.557: TestLongReg(LArgLong, LArgLong, LArgLong, LArgLong);
 008F8988 8D45E4           lea eax,[ebp-$1c]
008F898B 50               push eax
008F898C 8D4DE4           lea ecx,[ebp-$1c]
008F898F 8D55E4           lea edx,[ebp-$1c]
008F8992 8D45E4           lea eax,[ebp-$1c]
 008F8995 E88AFFFFFF       call TestLongReg
Unit1.pas.558: TestLongStd(LArgLong, LArgLong, LArgLong, LArgLong);
008F899A FF75F0           push dword ptr [ebp-$10]
008F899D FF75EC           push dword ptr [ebp-$14]
008F89A0 FF75E8           push dword ptr [ebp-$18]
008F89A3 FF75E4           push dword ptr [ebp-$1c]
008F89A6 8D45E4           lea eax,[ebp-$1c]
008F89A9 50               push eax
008F89AA 8D45E4           lea eax,[ebp-$1c]
008F89AD 50               push eax
008F89AE FF75F0           push dword ptr [ebp-$10]
008F89B1 FF75EC           push dword ptr [ebp-$14]
008F89B4 FF75E8           push dword ptr [ebp-$18]
008F89B7 FF75E4           push dword ptr [ebp-$1c]
008F89BA E891FFFFFF       call TestLongStd
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130429
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Издеваешься?
Нет. Я в асме не силён, мягко говоря. Но я адреса параметров сравнивал. На длинных структурах они всегда одинаковы при const, а без const - всегда разные. При любом соглашении вызова.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
type
  TRec = record
    a: Word;
    b: Word;
    c: Word;
  end;

procedure Test( {const} c: TRec ); //stdcall/pascal/cdecl;
begin
  ShowMessage( Format( '%x', [ Cardinal( @c ) ] ) );
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  c: TRec;
begin
  ShowMessage( Format( '%x', [ Cardinal( @c ) ] ) );
  Test( c );
end;


У меня D7
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130456
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Но я адреса параметров сравнивал.
Таки издеваешься
_Vasilisk_
Если соглашение вызова register, то все длинные структуры передаются по ссылке. А потом в функции параметры без const копируются в локальные переменные

YuRock
Я в асме не силён, мягко говоря
Учи :)
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130457
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще вот тут довольно подробно расписано, как параметры передаются:
https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Program_Control_(Delphi)
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130462
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
YuRock
Но я адреса параметров сравнивал.
Таки издеваешься
_Vasilisk_
Если соглашение вызова register, то все длинные структуры передаются по ссылке. А потом в функции параметры без const копируются в локальные переменные
Как оно там внутри - мне пофиг, честно говоря, если я знаю, что адрес структуры - не тот, что я передавал, и изменяя параметр я не изменю передаваемую в этот параметр структуру.
Это и значит - передача по значению (хоть бы и начиналась она с передачи ссылки).
...
Рейтинг: 0 / 0
Конвертация типов для работы с DLL C++ из Delphi
    #40130513
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Это и значит - передача по значению
Нет не значит. Возьми два компилятора. Скажем вызов на Делфи, а реализация на Си. Делфи отдала в функцию ссылку на свою структуру, а сишная функция эту структуру сможет модифицировать.

Кстати, достаточно функцию объявить как assembler и никакого копирования уже не будет
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Конвертация типов для работы с DLL C++ из Delphi
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]