Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.73/82: Рейтинг темы: голосов - 82, средняя оценка - 4.73
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307

Передача структуры данных в DLL (stdcall)

18.11.2009, 21:05. Показов 17765. Ответов 52
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Хочу передать данные следующей структуры в DLL:
Поле1: Символьный тип, длинной 15 букв (Pole_1: String[15])
Поле2: "Циферный" тип, длинной 5 цифр

И

Поле3: Символьный тип, длинной 15 букв (Pole_1: String[15])
Поле4: "Циферный" тип, длинной 5 цифр

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

Как мне указать длинну всех этих полей?

Delphi
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
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  procedure CobCall (WS_CAMPO1: String; WS_CAMPO2: String); stdcall;
  external 'COB.DLL' name'COBPROG';
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
WS_CAMPO1: String;
WS_CAMPO2: String;
begin
WS_CAMPO1:=Edit1.Text;
CobCall (WS_CAMPO1,WS_CAMPO2);
Edit2.text:=WS_CAMPO2;
end;
 
end.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.11.2009, 21:05
Ответы с готовыми решениями:

Передача структуры из программы на c# в dll на c++ и получение структуры из dll
В общем проблема в том, что при попытке передачи структуры созданной в c# в dll на c++ происходит событие pinvokestackimbalance Гуглил...

Конфликт forward и stdcall в dll-библиотеке
Добрый день. Есть некая библиотека library S_dll; uses ...; {$R *.res} var ... function LInit:Integer; stdcall;

Передача структуры из C# в DLL на C++
Здравствуйте! Вот такой вопросик, можете подсказать варианты передачи структуры в DLL написанную на C++? Есть обертка для DLL на...

52
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
24.11.2009, 15:34  [ТС]
Студворк — интернет-сервис помощи студентам
Mawrat, твой DLL я не смог запустить, callcobol.exe говорит что-то типа "В данном DLL не найдена функция COBPROG"
О начальной миссии - данные передаются правильно, за что большое спасибо, эта проблема решина!!! То есть передавая данные в TArrChar15 - кобол прога получает их правильно!!!

Теперь что касается новой проблемы - невозмоным является принять данные из кобол проги, ABEND-ов (Abnormal End) - я провёл такой эксперимент (ведь запуская программу из Delphi, дебугер оповещает при малейшей проблеме). А проблема возникает не во время GOBACK (по крайней мере в данном случае, передавая данные как TArrChar15), а во время MOVE CAMPO-1 TO CAMPO-2 в кобол программе.... Почему-то видать данные наезжают друг на друга в зарезервированной памяти, но почему не знаю, или что-то другое, что я не понимаю...
Заливаю COB.DLL который только выводит полученные 2 поля в консолу и возвращает контроль дельфи проге без каких-либо действий (кажется это ты хотел. Так как я проверил что она не глючит, уже не стал делать полностью пустую DLL, без принятия данных и каких-либо действий. И я убрал все вспомогательные переменные, единственные данные в проге это 2 поля нужные для соединения программ в LINKAGE SECTION, CAMPO-1, CAMPO2 )...

Ещё раз спасибо за помощь!
Вложения
Тип файла: rar COBDLL.rar (98.2 Кб, 16 просмотров)
0
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
24.11.2009, 15:37  [ТС]
БЛИН!!! Сейчас посмотрел - если я делаю MOVE "YUHU FUNCIONA!!" TO CAMPO-1 а не CAMPO-2, то Deplhi прога получает текст правильно без ошибок в CAMPO-1!!!!!!!!.......
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
24.11.2009, 15:45
Ок! Я рад, что всё получилось!
Если с передачей других COBOL типов через Dll будут проблемы - пиши. Будем подбирать "контейнеры" (типы данных) в Delphi.
1
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
24.11.2009, 15:59  [ТС]
Цитата Сообщение от Mawrat Посмотреть сообщение
Ок! Я рад, что всё получилось!
Если с передачей других COBOL типов через Dll будут проблемы - пиши. Будем подбирать "контейнеры" (типы данных) в Delphi.
Mawrat, большое спасибо!!! Только дело в том, что видать пока не всё получилось... Нет проблем если надо передавать лишь 1 параметр (данные), тогда можно стереть данные в CAMPO-1 которые передала Delphi прога и заменить их на другие в кобол проге, таким образом ответив Delphi проге... Но если данных несколько... Придётся использовать несколько полей, а в этом случае Delphi прога падает... Думаю мы близки от решения, осталось узнать почему если кобол программа отвечает данными в первом поле проблем нет, а если отвечает в последующих - Delphi прога падает...

И ещё не могу понять одного - не могу скомпилировать прогу когда пишу WS_CAMPO1:=Edit1.Text; пишет "Incompatible types 'TArrChar15' and 'TCaption'... А к Edit2.Text:=WS_CAMPO1; претензий у компилятора нет...

Delphi
1
2
3
4
WS_CAMPO1:=Edit1.Text;
CobCall (WS_CAMPO1, WS_CAMPO2);
Edit2.Text:=WS_CAMPO1;
Label1.Caption:=WS_CAMPO2;
А тогда как ввести данные из ЕditField в WS_CAPO1 для их передачи в кобол прогу?...
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
24.11.2009, 16:56
Цитата Сообщение от Kukstyler Посмотреть сообщение
осталось узнать почему если кобол программа отвечает данными в первом поле проблем нет, а если отвечает в последующих - Delphi прога падает...
У меня есть подозрение, что COBOL DLL передаёт данные не в стандарте stdcall, а например в pascal (хотя это может показаться странным конечно...). В таком случае, если передаётся только один параметр то вызов будет отрабатывать правильно и при stdcall и при pascal - т. к. в стек вызова помещается только одно значение. А вот если несколько параметров - здесь уже порядок следования парметров в стеке важен.
А... хотя нет - мы же в обоих случаях передаём 2 параметра... Хотя - не нет, а да - мы передаём 2 параметра, но описан как var именно второй, тогда в случае pascal правила мы при возвращении параметров из функции получим первым как раз второй параметр, видимо!
И можно попробовать так тогда:
Delphi
1
2
procedure CobCall (var WS_CAMPO1: TArrChar15; var WS_CAMPO2: TArrChar15); pascal;
  external 'COB.DLL' name 'COBPROG';
А затем разберемся какой параметр приходит из стека первым, а какой вторым.

Добавлено через 11 минут
Т. е. объявив функцию в Delphi программе таким образом, как написано выше, надо передать в качестве первого параметра значение:
'000000000000001'
А в качестве второго:
'000000000000002'
Затем в Cobol программе посмотреть в какой из переменных какое из значений пришло.
Если в Cobol программе окажется, что:
WS_CAMPO1 = '000000000000002'
WS_CAMPO2 = '000000000000001'
Значит Cobol DLL использует порядок обработки стека отличный от stdcall.

Добавлено через 1 минуту
Ой, напутал я там - в объявлении функции в Delphi программе надо пока оставить stdcall, а не pascal. А дальше по результатам эксперемента уже будет видно что делать - возможно придётся поменять на pascal.

Добавлено через 13 минут
Цитата Сообщение от Kukstyler Посмотреть сообщение
не могу скомпилировать прогу когда пишу WS_CAMPO1:=Edit1.Text; пишет "Incompatible types 'TArrChar15' and 'TCaption'... А к Edit2.Text:=WS_CAMPO1; претензий у компилятора нет...
TCaption - этот тип хоть и является псевдонимом String, тем не менее для компилятора TCaption и String - разные типы. Видимо в этом причина.
1
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
24.11.2009, 18:01  [ТС]
Mawrat, в случае stdcall кобол прога вообще не получает посланные данные в CAMPO_2:

http://img682.imageshack.us/im... tdcall.png

В случае pascal кобол прога их получает, но в обратном порядке как ты говорил, то есть данные переданные в CAMPO_1 в CAMPO-2, a переданные в CAMPO_2 в CAMPO-1:

http://img204.imageshack.us/img204/2196/pascal.png

Добавлено через 42 минуты
Кажется нашёл, в Коболе тоже можно указать Call-Convention, только по каким принципам из битов 6, 3 и 1 они получили 74 для WinAPI я не врубаюсь...

Code
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
      *     No bits specified means that the standard COBOL calling  *
      *     conventions are employed.  This means parameters are     *
      *     passed on a stack, last named is first pushed on the     *
      *     stack.  The parameters are removed from the stack by the *
      *     CALLer. Use this for compatibility with existing COBOL   *
      *     programs.                                                *
      *                                                              *
      *     The meaning of the numbers is derived from decomposing   *
      *     the number into binary components, with bits having      *
      *     the following meanings:                                  *
      *                                                              *
      *     0   -   parameters are passed on a stack, first named    *
      *             is first pushed.  So you could call this         *
      *             convention 'REVERSED'                            *
      *     1   -   The parameters are removed from the stack        *
      *             by the called routine                            *
      *     2   -   Reserved for future use                          *
      *     3   -   Ensure that the call name is resolved at link    *
      *             time rather than run time.                       *
      *     4   -   Reserved for use in the OS/2 product             *
      *     5   -   Reserved for use in the OS/2 product             *
      *     6   -   Use Win32 'stdcall' naming convention if the     *
      *             call is resolved at link time                    *
      *                                                              *
      *     The 'WINAPI' convention used by Win32 is obtained        *
      *     from a combination of bits 6, 3 and 1 giving a call      *
      *     convention value of 74                                   *
http://img692.imageshack.us/im... ntions.png

Нашёл интересную ссылку по той же теме но для Delphi
0
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
24.11.2009, 20:18  [ТС]
Так получается но передаётся только 14 символов, 15-ый нет...

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
var
  aux: String;
  idx: integer;
  WS_CAMPO1: TArrChar15;
 
begin
aux:=Edit1.Text;
idx:= 1;
SetLength(aux, 15);
for idx:= 1 to 15 do begin
WS_CAMPO1[idx]:=aux[idx];
end;
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
25.11.2009, 09:16
Если указывается stdcall, то параметры передаются в стек справа налево - т. е., согласно описанию функции, начиная с последнего справа параметра, затем - второй справа и т. д. - до самого первого слева. Когда процедура заканчивает выполнение, она сама должна очистить стек.
Соглашение cdecl - параметры передаются в том же порядке как и при stdcall, но стек должна очищать вызывающая программа.
Pascal соглашение - там передача параметров в стек осуществляется слева направо - в порядке их перечисления в описании функции. Очистка стека выполняется самой функцией.
Ещё есть fastcall - но там часть параметров передаются через регистры ЦПУ.
---
Т. е. нас устроит любое из правил, кроме fastcall. Конечно желательно было бы настроиться на stdcall - т. к. это стандарт для среды Windows.
---
Чтобы COBOL программу настроить на stdcall, как я понял в какой-то предназначенной для этого переменной следует записать побитно данные:
Бит №0: значение = 0 - устанавливает порядок передачи параметров в стек в направлении справа налево.
Бит №1: значение = 1 - стек очищает вызванная функция.
Только куда это прописывать в COBOL программе - не знаю, к сожалению.
Вот что-то такое из COBOL-доки:
PROCEDURE DIVISION stdcall USING parameter-1, parameter-2
Как бы прикрутить нечто подобное в COBOL-программу?
1
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
25.11.2009, 16:54  [ТС]
Кажется эта опция действует только в OO COBOL (Object Oriented)...
Да в принципе разницы нет, пусть будет pascal, главное что бы данные переходили из одной проги в другую правильно, а как это происходит, разницы нет!
Единственное что осталось это передать Edit1.Text в TArrayChar15...
Почему последний инициал из String в for не переходит в TArrayChar15 пока не понял... Экспериментирую...
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
25.11.2009, 20:42
Компилятор Delphi автоматически может преобразовывать данные символьных массивов в строки. Но наоброт - строки преобразовывать в символьные массивы он не может. Поэтому код:
ArrChar := Edit1.Text;
Не скомпилируется.
Чтобы перенести данные из строки в символьный массив можно действовать так как ты выше написал. Только с учётом того, что в нашем массиве элементы индексируются с нуля, а в строках - с единицы:
Delphi
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
uses
  Math;
...
procedure TForm1.Button1Click(Sender: TObject);
type
  TArrChar15 = array[0..14] of Char;
var
  ArrChar : TArrChar15;
  StrTmp  : String;
  i       : Integer;
begin
  //Очищаем массив ArrChar, чтобы в нём небыло мусора.
  for i := Low(ArrChar) to High(ArrChar) do begin
    ArrChar[i] := Char(0);
  end;
  
  //Переносим данные из Edit.Text в массив.
  for i := 0 to Min( High(ArrChar), (Length(Edit1.Text) - 1) ) do begin
    ArrChar[i] := Edit1.Text[i + 1];
  end;
  
  //Показываем сведения из символьного массива ArrChar.
  ShowMessage(ArrChar);
 
end;
Либо можно действовать через функцию Move - которая копирует содержимое блоков памяти.
Delphi
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
uses
  Math;
...
procedure TForm1.Button1Click(Sender: TObject);
type
  TArrChar15 = array[0..14] of Char;
var
  ArrChar : TArrChar15;
  StrTmp  : String;
  i       : Integer;
begin
  //Очищаем массив ArrChar, чтобы в нём небыло мусора.
  for i := Low(ArrChar) to High(ArrChar) do begin
    ArrChar[i] := Char(0);
  end;
  
//Переносим данные из Edit.Text в массив.
  //Используем выражение: Min( SizeOf(ArrChar), Length(Edit1.Text) * SizeOf(Char) )
  //для того чтобы при копировании не выйти за пределы массива ArrChar.
  //Move( PChar(Edit1.Text)^, ArrChar, Min( SizeOf(ArrChar), Length(Edit1.Text) * SizeOf(Char) ) );
 
  //Показываем сведения из символьного массива ArrChar.
  ShowMessage(ArrChar);
 
end;
В обоих случаях используем функцию Min() из модуля Math, для "умной" подгонки числа копируемых символов.
Оба кода примерно одинаковы по скорости копирования.
---
В конце кода:
ShowMessage(ArrChar);
Здесь компилятор автоматически преобразует символьный массив ArrChar в строку и передаёт полученную строку функции ShowMessage(). Обратное преобразование - из строки в массив - автоматически его Delphi выполнить не может и следует писать код, который приведён выше.
1
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
25.11.2009, 21:21  [ТС]
А я только что получил то что надо было сам, и спешу показать! В Delphi я знаю пока мало, но в конце концов вышло. Кстати, я убрал и проблему где если из 15 символов в Edit1.Text заполнено не 15, то остальные заполнялись Бог знает чем, теперь всё как надо, все незаполненные передаются как пробелы (Spaces)!

Delphi
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
35
36
37
38
39
type
  TArrChar15  = array[1..15] of Char;
procedure CobCall (var WS_CAMPO3: TArrChar15; var WS_CAMPO2: TArrChar15;
    var WS_CAMPO1: TArrChar15);  pascal; external 'COB.DLL' name'COBPROG';
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
  aux: String[15];
  idx: integer;
  WS_CAMPO3: TArrChar15;
  WS_CAMPO2: TArrChar15;
  WS_CAMPO1: TArrChar15;
begin
WS_CAMPO1:='               ';
WS_CAMPO2:='               ';
WS_CAMPO3:='               ';
aux:=      '               ';
aux:=Edit1.Text;
 
for idx:= 1 to 15 do begin
  WS_CAMPO1[idx]:=aux[idx];
end;
 
Button1.Caption:='['+aux+']';
 
//WS_CAMPO1:='000000000000001';
//WS_CAMPO2:='ABC            ';
//WS_CAMPO3:='000000000000003';
 
CobCall (WS_CAMPO3, WS_CAMPO2, WS_CAMPO1);
 
Edit1.Text:=WS_CAMPO1;
Edit2.Text:=WS_CAMPO2;
Edit3.Text:=WS_CAMPO3;
end;
end.
Добился я и что бы все 15 символов из Edit1Text переходили в TArrayChar15, именно меняя 0..14 на 1..15 в Type TArrayChar15. Проверил - данные по прежнему получаются и выдаются в кобол проге правильно. Хорошо что не нужнo делать SetLenght, а то он страшные вещи помещал в aux!...

Всем большое спасибо за ответы, особенный респект тебе, Mawrat, век не забуду! Если будут проблемы - ещё тебя побеспокою (раз уж предложил)...
Ну и конечно, если чем могу - тоже с радостью. Речь идёт не только о кобол программах, я ещё кое в чём разбираюсь
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
25.11.2009, 21:38
Цитата Сообщение от Kukstyler Посмотреть сообщение
Ну и конечно, если чем могу - тоже с радостью. Речь идёт не только о кобол программах, я ещё кое в чём разбираюсь
Спасибо.
Цитата Сообщение от Kukstyler Посмотреть сообщение
Добился я и что бы все 15 символов из Edit1Text переходили в TArrayChar15, именно меняя 0..14 на 1..15 в Type TArrayChar15.
Да - можно так - это удобно.
Если не менять индексацию, то в предыдущем своём посте я писал:
Delphi
1
2
3
4
5
6
7
type
  TArrChar15 = array[0..14] of Char;
...
  //Переносим данные из Edit.Text в массив.
  for i := 0 to Min( High(ArrChar), (Length(Edit1.Text) - 1) ) do begin
    ArrChar[i] := Edit1.Text[i + 1];
  end;
Если без заморок с Min(), то так (При условии, что строка в Edit1.Text содержит не меньшее количество символов, чем длина ArrChar) :
Delphi
1
2
3
4
5
6
7
type
  TArrChar15 = array[0..14] of Char;
...
  //Переносим данные из Edit.Text в массив.
  for i := 0 to High(ArrChar) do begin
    ArrChar[i] := Edit1.Text[i + 1];
  end;
А для того, чтобы мусора небыло в массиве, это тоже в моём предыдущем посте упомянуто :
Delphi
1
2
3
4
  //Очищаем массив ArrChar, чтобы в нём небыло мусора.
  for i := Low(ArrChar) to High(ArrChar) do begin
    ArrChar[i] := Char(0);
  end;
Этот код очистки не зависит от того какая выбрана индексация элементов массива ArrChar - от нуля или от единицы или ещё как-то.
И заполнять нулевым кодом - Char(0) - предпочтительнее. Пробел - это всё-таки значащий строковый символ.
1
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
25.11.2009, 22:25  [ТС]
Спасибо большое за ещё одно детальное обяснение всему! Думаю по-немногу буду "тюнинговать" всю эту затею и всё это мне более чем пригодится!
А что касается пробелов - в COBOL-е чаще используют именно их, по-этому в данном случае это даже хорошо.
1
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
02.12.2009, 00:51  [ТС]
Mawrat, во имя демонстрации результатов нашего пота, выкладываю созданное, оказывается я забыл залить ещё один DLL, потомy прога у тебя и не открывалась!...

И так в пакете:
  • CallCobol.exe - Дельфи прога
  • COB.DLL - Кобол прога
  • CBLRTSS.DLL - MicroFocus COBOL Single-Thread Run-Time System
  • CBLVIOS.DLL - Micro Focus Console Support
Вложения
Тип файла: rar CALL COBOL.rar (310.2 Кб, 14 просмотров)
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
02.12.2009, 09:34
Kukstyler, к сожалению, CRC ерор в архиве.

Добавлено через 2 минуты
Kukstyler, скачал.

Просьба к модераторам - это моё сообщение удалите, пожалуйста.
0
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
02.12.2009, 16:38  [ТС]
Значит работает, да?
0
 Аватар для Mawrat
13117 / 5898 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
02.12.2009, 18:25
Да - всё нормально распаковалось. И работает.
1
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
02.12.2009, 22:43  [ТС]
Блииииин! COB.DLL не тот был, вот хорошый!
Вложения
Тип файла: zip COB.zip (2.0 Кб, 16 просмотров)
1
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
25.01.2010, 23:04  [ТС]
Mawrat, привет. Похоже тут что-то не так или я чё-то не так делаю, весь день бьюсь но никак не пойму в чём дело... Решил применить найденный нами метод в реале, с реальной прогой, сделал вроде всё как в прошлый раз, но при вызове кобол проги передаётся только содержимое первого поля, а потом полная белиберда....
Скомпилированный вариант в аттачах, тут же и код... Глянь если можешь когда будет время

Delphi
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, XPMan;
type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    ListBox1: TListBox;
    XPManifest1: TXPManifest;
    GroupBox2: TGroupBox;
    Edit1: TEdit;
    validar: TButton;
    limpiar: TButton;
    GroupBox3: TGroupBox;
    RESPUESTA: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Edit2: TEdit;
    MENSAJE: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
    procedure VALIDARClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
type
  X30  = array[1..30] of Char;
  X80  = array[1..80] of Char;
  X3   = array[1..3]  of Char;
  X6   = array[1..6]  of Char;
  X26  = array[1..26] of Char;
  X8   = array[1..8]  of Char;
  X10  = array[1..10] of Char;
  X72  = array[1..72] of Char;
procedure CobCall (var WS_FILLER: X30;
                   var WS_DESCRIP: X80;
                   var WS_RC: X3;
                   var WS_NUMMER: X6;
                   var WS_OUT_STAMP: X26;
                   var WS_OUT_TIME: X8;
                   var WS_OUT_DATE: X10;
                   var WS_INDATA: X72;
                   var WS_OPCION: X3);
        pascal; external 'PBDMR001.dll' name'PBDMR001';
 
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
  ListBox1.Items.Add('1  - Validar una Fecha, Formato: AAAA-MM-DD');
  ListBox1.Items.Add('2  - Validar una Hora');
  ListBox1.Items.Add('3  - Validar TIMESTAMP');
  ListBox1.Items.Add('4  - Sumar un número de días a una fecha');
  ListBox1.Items.Add('5  - Sumar un número de meses a una fecha');
  ListBox1.Items.Add('6  - Sumar un número de años a una fecha');
  ListBox1.Items.Add('7  - Sumar un número de horas a la hora indicada');
  ListBox1.Items.Add('8  - Sumar un número de minutos a la hora indicada');
  ListBox1.Items.Add('9  - Sumar un número de segundos a la hora indicada');
  ListBox1.Items.Add('10 - Sumar un número de días a TIMESTAMP');
  ListBox1.Items.Add('11 - Sumar un número de meses a TIMESTAMP');
  ListBox1.Items.Add('12 - Sumar un número de años a TIMESTAMP');
  ListBox1.Items.Add('13 - Sumar un número de horas a TIMESTAMP');
  ListBox1.Items.Add('14 - Sumar un número de minutos a TIMESTAMP');
  ListBox1.Items.Add('15 - Sumar un número de segundos a TIMESTAMP');
  ListBox1.Items.Add('16 - Calcular la diferencia en días entre 2 fechas');
  ListBox1.Items.Add('17 - Calcular la diferencia en segundos entre 2 horas');
  MENSAJE.Caption := '';
  ListBox1.ItemIndex:=0;
end;
procedure TForm1.Edit1Change(Sender: TObject);
begin
  IF  (Edit1.Text = '') or
      (Edit1.Text = ' ') then
      begin
      VALIDAR.Enabled := false;
//     LIMPIAR.Enabled := false;
      Edit1.Text := '';
      end
  else
      begin
      VALIDAR.Enabled := true;
//      LIMPIAR.Enabled := true;
  end;
 
end;
procedure TForm1.VALIDARClick(Sender: TObject);
var
//*************************************************
//* CAMPO AUXILIAR ESPACIOS Y PASAR EDIT.TEXT
//*************************************************
  aux: String[72];
//*************************************************
//*               CAMPO INDICE
//*************************************************
  idx: integer;
//*************************************************
//*           CAMPOS DE LA LINKAGE
//*************************************************
  WS_FILLER    : X30;
  WS_DESCRIP   : X80;
  WS_RC        : X3;
  WS_NUMMER    : X6;
  WS_OUT_STAMP : X26;
  WS_OUT_TIME  : X8;
  WS_OUT_DATE  : X10;
  WS_INDATA    : X72;
  WS_OPCION    : X3;
begin
//*************************************************
//*               LA PROCEDURE
//*************************************************
//-------- PASA OPCION
if  ListBox1.ItemIndex=0 then
    begin
    WS_OPCION:='001';
end;
if  ListBox1.ItemIndex=1 then
    begin
    WS_OPCION:='002';
end;
if  ListBox1.ItemIndex=2 then
    begin
    WS_OPCION:='003';
end;
if  ListBox1.ItemIndex=3 then
    begin
    WS_OPCION:='004';
end;
if  ListBox1.ItemIndex=4 then
    begin
    WS_OPCION:='005';
end;
if  ListBox1.ItemIndex=5 then
    begin
    WS_OPCION:='006';
end;
if  ListBox1.ItemIndex=6 then
    begin
    WS_OPCION:='007';
end;
if  ListBox1.ItemIndex=7 then
    begin
    WS_OPCION:='008';
end;
if  ListBox1.ItemIndex=8 then
    begin
    WS_OPCION:='009';
end;
if  ListBox1.ItemIndex=9 then
    begin
    WS_OPCION:='010';
end;
if  ListBox1.ItemIndex=10 then
    begin
    WS_OPCION:='011';
end;
if  ListBox1.ItemIndex=11 then
    begin
    WS_OPCION:='012';
end;
if  ListBox1.ItemIndex=12 then
    begin
    WS_OPCION:='013';
end;
if  ListBox1.ItemIndex=13 then
    begin
    WS_OPCION:='014';
end;
if  ListBox1.ItemIndex=14 then
    begin
    WS_OPCION:='015';
end;
if  ListBox1.ItemIndex=15 then
    begin
    WS_OPCION:='016';
end;
if  ListBox1.ItemIndex=16 then
    begin
    WS_OPCION:='017';
end;
 
//---------------------------
//       INICIALIZA
//---------------------------
WS_FILLER :='                              ';
WS_RC     :='   ';
WS_NUMMER :='      ';
WS_OUT_STAMP:='                          ';
WS_OUT_TIME:='        ';
WS_OUT_DATE:='          ';
for idx:= 1 to 80 do begin
    WS_DESCRIP[idx]:=' '
end;
for idx:= 1 to 72 do begin
    WS_INDATA[idx]:=' '
end;
aux:=
'                                                                        ';
 
//==============================================================================
//aux:=Edit1.Text;
//for idx:= 1 to 72 do begin
//    WS_INDATA[idx]:=aux[idx]
//end;
 
//---------------------------
//   LLAMADA RUTINA COBOL
//---------------------------
CobCall (WS_FILLER,
         WS_DESCRIP,
         WS_RC,
         WS_NUMMER,
         WS_OUT_STAMP,
         WS_OUT_TIME,
         WS_OUT_DATE,
         WS_INDATA,
         WS_OPCION);
//---------------------------
Edit2.Text:=WS_RC;
MENSAJE.Caption:=WS_DESCRIP;
end;
end.
Вложения
Тип файла: zip NURIA.zip (414.4 Кб, 8 просмотров)
0
 Аватар для Kukstyler
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
28.01.2010, 18:29  [ТС]
Кажется у меня появилась идея которая работает. Если передавать не структуру а одну переменную Н-ного размера то всё передаётся хорошо, и естественно не в обратном порядке структуры.
То есть я связал всё в одну переменную X238 = array[1..238] of Char; и при помощи нескольких for записал данные в нужном порядке, похоже пашет!!! Надо ещё хорошо посмотреть, но кажется работает!

Delphi
1
2
3
4
5
idx2:= 1;
for idx:= 4 to 75 do begin
    WS_pasadatos[idx]:=aux[idx2];
    idx2:=idx2+1;
end;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.01.2010, 18:29

Передача дополнительного аргумента в функцию stdcall/cdecl?
Всем доброго дня! Есть функция func вида: __stdcall void func() { cout<<"func"<<endl; }

Сделать отладочную DLL (изменить cdecl на stdcall) для вызова из VB
Добрый день. А как обнаружить свой адрес при входе в функцию какой-либо DLL-ки ? А по русски говоря: Сохранить регистр EIP. У...

Передача структуры в dll валит ЕХЕ файл.
Имеется структура в VB Type ST Field1 As String Field2 As Long Field3 As String Field4 As String End Type ...

Передача данных в dll
Есть .dll: library dll; uses Windows, WinInet, SysUtils, TlHelp32, UrlMon, Dialogs; var text : string; {$R *.res}

Формирование и передача структуры данных!
Здравствуйте! Пишу сам себе курсовую работу!ASP.NET MVC. Сайт. Столкнулся с такой ситуацией. На вход формы приходит список из...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru