DLL из Delphi в VB

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Odrick
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 503
Зарегистрирован: 28.09.2003 (Вс) 2:04

DLL из Delphi в VB

Сообщение Odrick » 08.07.2005 (Пт) 22:14

Или я чего то не понимаю, или с двух одно... :D
В общем есть такой глюк (или не глюк?) - пишем dll на Delphi, вызываем ее функцию из VB. Если в качестве параметра передавать константу, все Ок. Но если передать переменную, то вместо ее значения функция получает нечно вовсе не похожее. Самое интересное дальше. Если проводить математические операции и возвращать значения, то результат оказываеться верным. Однако, если внутри функции применять операции сравнения, то все, фонарь - параметр обрабатываеться некорректно. Вот конкретно пример dll на Delphi:

Код: Выделить всё
library DelphiDLL;

uses
  SysUtils,
  Dialogs;

Function TestDelphiDLL (X: Integer): Integer; export; stdcall;
begin
  ShowMessage ('X = ' + IntToStr(X));
  TestDelphiDLL := X*10;
end;

exports
  TestDelphiDLL;

begin
end.


Объявление в VB:
Код: Выделить всё
Private Declare Function TestDelphiDLL Lib "DelphiDLL" (ByVal X As Integer) As Integer


Если вызываем так:
Код: Выделить всё
intRes = TestDelphiDLL(10)

сообщение из dll показывает правильное значение параметра = 10.

Если так:
Код: Выделить всё
Dim intX As Integer
   
intX = 10
intRes = TestDelphiDLL(intX)

сообщение из dll показывает значение параметра = -65526...

Вот такая загогулина. Какое может быть объяснение сему феномену? В какую сторону копать? В сторону VB или Delphi? Или в сторону моих кривых рук? :wink: Могу выложить еще скомпиленую dll и тест на VB. Правда все это килобайт 200 будет...[/code]
То, что для одних константа, для других только переменная...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 08.07.2005 (Пт) 23:55

Точно-точно кривые руки.
В Delphi integer - 4 байта, а в VB - 2. Переобъяви ByVal X As Long, должно всё быть пучком.
Изображение

Odrick
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 503
Зарегистрирован: 28.09.2003 (Вс) 2:04

Сообщение Odrick » 09.07.2005 (Сб) 1:37

Да, спасибо, помогло. Чесно говоря меня ввели в заблуждение (и до сих пор остаються не совсем понятными) несколько факторов:

1. Почему при передаче константы, все срабатывает нормально? Ну это еще можно объяснить какими-нить обработками данных самим VB.
2. Почему математические операции над "корявыми" данными происходят нормально? И возвращают правильный результат? В моем примере, хоть dll видит вместе 10 -65526, результат вычисления X*10 возвращает 100?

Да, то есть если в функции dll параметры будут типа SmallInt (2 байта), а в VB Integer, то все будет в порядке? Сейчас попробую...
То, что для одних константа, для других только переменная...

AsDev
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 30.10.2004 (Сб) 11:50

Сообщение AsDev » 10.07.2005 (Вс) 9:25

Глюк происходит потому,что в объявлениях функции в дельфовой библиотеке параметр должен передаваться по значению,т.к у тебя отсутствует ключево слово var,а VB по умолчанию передаёт парметры по ссылке (byref).Чтобы не глючило пропиши в библе примерно так:

function My(var x:integer):integer;

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 10.07.2005 (Вс) 9:50

AsDev, а то, что в объявлении функции прописано ByVal, тебя не смущает?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Odrick
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 503
Зарегистрирован: 28.09.2003 (Вс) 2:04

Сообщение Odrick » 10.07.2005 (Вс) 18:57

AsDev позволю себе не согласиться :wink: var используеться для объявления "возвратных" параметров. То есть передаеться ссылка на переменную, а не ее значение и функция имеет возможность изменять значение даной переменной. В моем примере как раз и в делфи и в VB параметры передаються как значения. Для этого и служит ключевое слово ByVal. В общем чего-то еще не знаю, или не понимаю...
То, что для одних константа, для других только переменная...

AsDev
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 30.10.2004 (Сб) 11:50

Сообщение AsDev » 11.07.2005 (Пн) 16:28

Пропиши в объявлениях не ByVal,а ByRef :P

Odrick
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 503
Зарегистрирован: 28.09.2003 (Вс) 2:04

Сообщение Odrick » 11.07.2005 (Пн) 16:44

А смысл? Если размерность Integer в Delphi 4 байта? Ну получит функция ссылку, ну прочитает по ней 4 байта, вместо 2-х, интерпретирует их и получит тот же бред ;) В общем с размерностью уже разобрались. Смысл вопроса уже не в этом. Смысл в том, ПОЧЕМУ константа правильно передаеться, и ПОЧЕМУ внутри функции выражение -65526 * 10 дает в результате 100?
То, что для одних константа, для других только переменная...

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Сообщение Vi » 12.07.2005 (Вт) 13:11

Odrick писал(а):Смысл вопроса уже не в этом. Смысл в том, ПОЧЕМУ константа правильно передаеться

Это не так важно. Дело в несоответствии передачи 16-битного целого и приёма 32-битного. При копировании в стек, константа может заполнить все 32-битное слово стека, а может и нет. Точно так же копирование 16-разрядной переменной. Ты можешь передавать с равной долей вероятности любое значение &HXXXX000A (от &H0000000A до &HFFFF000A). Какое - зависит от состояния стека и работы подпрограмм VB.
Odrick писал(а):и ПОЧЕМУ внутри функции выражение -65526 * 10 дает в результате 100?

Число &HXXXX000A, которое ты передал функции, правильно умножается на число 10. В результате получается число &HYYYY0064. Но VB при получении обрезает то, что считает лишним, т.к. ему требуется только 2 байта, и передает в переменную уже обрезанную часть &0064 == 100. Если ты объявишь функцию как возвращающую не Integer, а Long, то получишь ошибку преобразования.
ADDITION
Последнее замечание к тому, что передается в действительности полное число &HYYYY0064, которое не переводится в Integer. Если бы передавалось реальное 100, то и ошибки бы не было.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

Odrick
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 503
Зарегистрирован: 28.09.2003 (Вс) 2:04

Сообщение Odrick » 12.07.2005 (Вт) 13:20

Ага, вот теперь стало все понятно. Да, действительно про это я не подумал. Ну что ж, всем спасибо :D
То, что для одних константа, для других только переменная...


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14

    TopList  
cron