Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: взаимодействие ДЛЛ на C++ и Delphi  (Прочитано 17897 раз)
0 Пользователей и 1 Гость смотрят эту тему.
nesluh
Гость
« : 05-03-2008 17:44 » 

Здравствуйте. У меня следующая проблема:
написал DLL на С++ и подключил динамически к проекту на Дельфе.
Из длл экспортируется всего одна функция, в которую передаются указатель на структуру (вернее на некий элемент списка) и три целочисленных параметра. Решил опробовать что из этого вышло: для начала сделал так Sort(nil, -1,-1,-1), функция при этом должна была бы просто завершится ничего не возвращая (функция типа void, соответственно в Дельфе описана как процедура). Что я получил? что-то по адресу такому-то не может записать что-то по адресу такому-то. Ну ладно, создал реальный элемент структуры и отправил указатель на него в функцию и решил посмотреть из MVS, что же там творится. И был искренне удивлен, когда вместо необходимого мне адреса я увидел какой-то совершенно левый, а поля целочисленного типа принимали значения от 0 до 3000000 (вместо положенных -1). Ну и есстественно, что когда я решил просмотреть, что хранится по этому адресу по полям моей структуры я увидел:"expression cannot be evaluated"
Структура описана в Дельфи, как
Цитата
PNomer=^Nomer;
Nomer = record
klas: real;
KolKom: integer;
Ploshad: real;
Etazh: integer;
Stoimost: real;
DataVezd: TDate;
Svobod: bool;
Next: PNomer;
Prev: PNomer;
end;
соответствие в моей длл:
Цитата
struct Nomer{
double klas;
int KolKom;
double Ploshad;
int Etazh;
double Stoimost;
double DataVezd;
bool Svobod;
Nomer* Next;
Nomer* prev;
};
Описание функции в Дельфи и ее вызов:
Цитата
TSort = procedure (var first: PNomer; pole1, pole2, pole3:integer); stdcall;
...
...
...
Handles:=LoadLibrary('DL.dll');
if handles<>0 then
begin
@Sort := GetProcAddress(Handles, '_Sort@16');
if(@Sort=nil) then
begin
ShowMessage('Not Found');
exit;
end;
Sort(first,-1,-1,-1);
FreeLibrary(Handles);
ее же описание в длл:
Цитата
extern "C" __declspec(dllexport) void __stdcall Sort(Nomer* first, int pole1,int pole2,int pole3)
в чем проблема? чего я чайник не понимаю?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 05-03-2008 22:08 » 

nesluh, я не делал как у тебя - у меня в точности наоборот. Взял модули delphi, создал в BC++ dll-проект, добавил туда модули. Он сам сгенерил C++ заголовки и lib-файл для борландовских проектов. Может тебе стоит взять похожуу стратегию: сделать в Delphi dll-проект и добавить в него C++ файлы - может тоже какие чудеса есть...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
nesluh
Гость
« Ответ #2 : 06-03-2008 03:09 » 

RXL, насколько я понимаю под
Цитата
BC++
ты имеешь ввиду Borland С++ Builder? в принципе Я пока под ним попробую откомпилировать свою  длл-ку, а вот по поводу С++ кода в Дельфи я, честно говоря, сомневаюсь.
Записан
zubr
Гость
« Ответ #3 : 06-03-2008 05:16 » 

nesluh, проблема скорее всего в параметре var. Попробуй вместо TSort = procedure (var first: PNomer; pole1, pole2, pole3:integer); stdcall; сделать TSort = procedure (first: Pointer; LengthNomer:Integer; pole1, pole2, pole3:integer); stdcall; соответственно в dll: extern "C" __declspec(dllexport) void __stdcall Sort(Nomer* first, int LengthNomer,int pole1,int pole2,int pole3)

Записан
zubr
Гость
« Ответ #4 : 06-03-2008 07:26 » 

В принципе должно работать если просто убрать var: TSort = procedure (first: PNomer; pole1, pole2, pole3:integer); так как PNomer у тебя это указатель на структуру. Ключевое слово var заставляет компилятор в Delphi передавать параметр по ссылке - в результате у тебя получается указатель на указатель, поэтому естественно с длл работает некорректно.
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 06-03-2008 07:41 » 

zubr, а ссылочный тип в Delphi несовместим со ссылочным типом в C++? (то есть, если в дельфи - var first:PNomer, а в C++ PNomer& first - это не будет вместе работать? Улыбаюсь ) А то вдруг появится надобность изменять значения передаваемых параметров - это только при передаче по указателю останется возможным сделать?
Записан
sss
Специалист

ru
Offline Offline

« Ответ #6 : 06-03-2008 09:00 » 

Вад, проблема как раз в том, что он передает адрес указателя... А так нет никаких проблем, var и & одно ито же...
« Последнее редактирование: 06-03-2008 09:02 от sss » Записан

while (8==8)
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 06-03-2008 09:17 » 

sss, тогда ничто не мешает сделать обратное: не убрать передачу по ссылке, а добавить её в C++-объявлении? Понятно, что для указателя это, может быть, не лучшее решение, особенно если его никто не планирует изменять, речь просто о самом принципе, что обратное решение тоже работает: если в дельфи var, то в С++ - &. Можно ещё тему константных ссылок развить Улыбаюсь
Записан
zubr
Гость
« Ответ #8 : 06-03-2008 09:24 » 

Вад, можно и так как ты предлагаешь, только в данном случае наверно не нужен указатель на указатель.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #9 : 06-03-2008 09:53 » 

Вад, ему надо объявить 
Код:
extern "C" __declspec(dllexport) void __stdcall Sort( Nomer** first, int pole1,int pole2,int pole3)
или ( хотя не уверен проглотит компилятор?)
Код:
extern "C" __declspec(dllexport) void __stdcall Sort( Nomer* &first, int pole1,int pole2,int pole3)

и все будет чики-чики... Вот только не знаю real == double? Мне кажется real 8 байт...
Записан

while (8==8)
nesluh
Гость
« Ответ #10 : 06-03-2008 16:14 » 

Благодарю всех, ближе к вечеру попробую предложенные варианты. А first мне менять придется - по сути у меня идет сортировка списка. Кстати, а почему параменты int-овские так резко скачут?
« Последнее редактирование: 06-03-2008 16:23 от nesluh » Записан
zubr
Гость
« Ответ #11 : 06-03-2008 17:18 » 

Цитата
Кстати, а почему параменты int-овские так резко скачут?
Потому что ты обращаешься не по адресу памяти, где расположена структура, а по ссылке на этот адрес и функция начинает брать данные по параметрам по адресу ссылки - а там может быть что угодно.
Записан
nesluh
Гость
« Ответ #12 : 07-03-2008 03:02 » new

структура
я не про те, что лежат в структуре, а про те, что передаются в функцию по значению:
Sort( Nomer* &first,int pole1,int pole2,int pole3 )
« Последнее редактирование: 07-03-2008 03:05 от nesluh » Записан
zubr
Гость
« Ответ #13 : 07-03-2008 05:08 » 

Ну и я про те. Компилятор под переменную first в dll-функции Sort(Nomer* first, int pole1,int pole2,int pole3) выделяет размер этой структуры, затем идут параметры int pole1,int pole2,int pole3, то есть значение pole1 находится по адресу &first+SizeOf(Nomer). А в дельфийской функции у тебя под первый параметр функции дана ссылка (4 байта), то есть адрес pole1=@first+4
Записан
sss
Специалист

ru
Offline Offline

« Ответ #14 : 07-03-2008 05:25 » 

nesluh, предлагаю тебе показать какой код у тебя сейчас.

Должно быть что-то вроде.

Код:
//Delphi
TSort = procedure ( first: PNomer; pole1, pole2, pole3:integer); stdcall;
и вызов
Sort( @first, -1,-1,-1);

//VC
extern "C" __declspec(dllexport) void __stdcall Sort( Nomer* first, int pole1,int pole2,int pole3)
Записан

while (8==8)
nesluh
Гость
« Ответ #15 : 08-03-2008 16:30 » 

благодарю всех Класс! , пока в тестовом варианте заработало. Будут проблемы с рабочим - напишу.
пока что в длл у меня написано:
Код:
extern "C" __declspec(dllexport) void __stdcall Sort( Nomer* &first, int pole1,int pole2,int pole3)
в дельфи:
Код:
TSort = procedure ( first: PNomer; pole1, pole2, pole3:integer); stdcall;
вызов:
Sort( first, -1,-1,-1);
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines