Форум программистов, компьютерный форум, киберфорум
Matlab
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/65: Рейтинг темы: голосов - 65, средняя оценка - 4.57
0 / 0 / 0
Регистрация: 05.08.2011
Сообщений: 3

Matlab dll и Delphi

05.08.2011, 10:11. Показов 12809. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Необходимо связать dll, созданную в MATLAB, и программу, написанную в Delphi.
Для пробы создаю additor.m:

function result = additor(x,y)
result = x + y;

Командой 'mcc -l additor.m' MATLAB Version 7.7.0.471 (R2008b) создаётся additor.dll и ещё куча файлов.

При просмотре dll видны следующие функции Imports/Exports:
_additorGetMcrID
_additorInitialize
_additorInitializeWithHandlers
_additorPrintStackTrace
_additorTerminate
_mlfAdditor
_mlxAdditor


Далее, в Delphi 6.0 пишу следующий код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
procedure _additorInitialize; stdcall; external 'additor.dll'; 
 function _mlxAdditor(x,y:real):real; stdcall; external 'additor.dll'; 
 
 procedure TForm1.Button1Click(Sender: TObject); 
 var a,b,c:real; 
 begin 
 _additorInitialize; 
 a:=1; 
 b:=2; 
 c:=_mlxAdditor(a,b); 
 Label1.Caption:=floattostr(c); 
 end;
Компилируется. После выполнения с принимает значение NAN.
В чём тут может быть дело?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.08.2011, 10:11
Ответы с готовыми решениями:

Подключение DLL - файлов к MatLab
Добрый день/вечер/ночь. Столкнулся я с такой проблемой: у меня имеется электронейромиограф(штука, которая снимает электрические...

Простейший DLL на С и его loadlibrary in matlab
В VC 2010 создаю пустой консольный проект dll Вот вот простейшие три функции targ1.cpp #include <windows.h> #include...

Delphi and matlab
помогите пожалуйста сделать это в матлаб: if ComboBox1.ItemIndex = 2 then begin for i:=1 to (N div 2) do begin if A > A then...

18
132 / 129 / 31
Регистрация: 12.12.2011
Сообщений: 462
12.12.2011, 15:57
Вопрос еще актуален?
0
0 / 0 / 0
Регистрация: 05.08.2011
Сообщений: 3
12.12.2011, 17:51  [ТС]
Да, вопрос ещё актуален.
0
132 / 129 / 31
Регистрация: 12.12.2011
Сообщений: 462
13.12.2011, 13:55
Я тоже долго бился, прежде чем смог заставить свое Delphi приложение нормально воспринимать dll, созданные из m-файлов. Я так понял, что нужно создать автономное приложение, которое использовало бы мат. возможности MatLab?
В общем наткнулся на это: http://sevntu.com.ua/jspui/bit... 100002.pdf
Там подробно описано как делать dll через матлабовский DeploymentTool и предоставлен код Delphi. Только как я понял, это пройдет на матлаб 7. А у меня был 2010b. В общем, как написано в статье не получилось
Я сделал так:
1)Создал dll через Deployment Project (см. статью)
2)Установил среду MCR (см. статью)
3)(Теперь важно, именно после этого заработало!) Добавил в переменные среды три константы ведущие к MCR, чтобы приложение видело библиотеки. В моем варианте:
C:\Program Files\MATLAB\MATLAB Compiler Runtime\v714\runtime\win32;
C:\Program Files\MATLAB\MATLAB Compiler Runtime\v714\runtime\bin;
C:\Program Files\MATLAB\MATLAB Compiler Runtime\v714\bin\win32;
ОБЯЗАТЕЛЬНО ПЕРЕД константами, связанными с директорией, куда установлен матлаб, иначе приложение тупит и вылетает без ошибок и предупреждений.

Теперь по поводу кода.
Я не использовал функцию mclInitializeApplication, как сказано в статье. Во-первых и без нее все работает, а во-вторых, я ее попросту не нашел. Была только mclInitializeApplication_proxy. Но от нее толку не было. Достаточно просто инициализировать свою dll.
При директиве StdCall все работало но вылезали ошибки, которые пропали при смене StdCall на Cdecl.
Как я понял из статьи, то все экспортируемые функции из созданной в матлабе dll это процедуры. Т.е. к ним нельзя обратиться в выражении (может это не точно, надо бы еще раз перечитать). Там первый параметр - число выходных параметров (Integer), а остальное - выходные и входные параметры. Например функция для перемножения матриц (см статью) у меня описана так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
unit Unit2;
 
interface
 
type
    pDouble = ^Double;
    mxComplexty = (mxREAL, mxCOMPLEX);
    pmxArray = ^mxArray;
    mxArray = record end;
 
procedure mlfMatrixMULTIPLICATION(i:Integer; var pout:pmxArray; A,B:pmxArray);cdecl; external 'matr_dll.dll';
а вызываю я ее так:
Delphi
1
mlfMatrixMULTIPLICATION(1,C,A,B);
Надеюсь, что поможет. Если будут вопросы, спрашивай. Будем разбираться. Мне просто тоже кровь из носа надо юзать матлаб в своих приложениях - много считать надо. Так что пришлось за две недели разобраться, как это делается. Вот только в матлабе я пока не силен!
2
0 / 0 / 0
Регистрация: 05.08.2011
Сообщений: 3
14.12.2011, 10:25  [ТС]
Спасибо! Буду пробовать!
0
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 8
14.02.2012, 10:59
Цитата Сообщение от Vabos Посмотреть сообщение
3)(Теперь важно, именно после этого заработало!) Добавил в переменные среды три константы ведущие к MCR, чтобы приложение видело библиотеки. В моем варианте:
C:\Program Files\MATLAB\MATLAB Compiler Runtime\v714\runtime\win32;
C:\Program Files\MATLAB\MATLAB Compiler Runtime\v714\runtime\bin;
C:\Program Files\MATLAB\MATLAB Compiler Runtime\v714\bin\win32;
ОБЯЗАТЕЛЬНО ПЕРЕД константами, связанными с директорией, куда установлен матлаб, иначе приложение тупит и вылетает без ошибок и предупреждений.
Подскажите пожалуйста, как это сделать?
Сделал все кроме этого и правда вылетает программа без ошибок и предупреждений.
Правда я пользуюсь
mclInitializeApplication(0,0); - нормально проходит
_matr_dllInitialize; - при ее вызове вылетает программа без предупреждений

а при вызове _mlfPlusvak(1,C,A,B); (функция для сложения) - вылетает с ошибкой (принтскрин прикреплен к посту)

на всякий случай привожу код
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
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
unit main;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
  type
    pDouble = ^Double;
    mxComplexty = (mxREAL, mxCOMPLEX);
    pmxArray = ^mxArray;
    mxArray = record end;
 
procedure _mlfPlusvak(i:Integer; var pout:pmxArray; A,B:pmxArray);cdecl; external 'matr_dll.dll';
function _matr_dllInitialize:Boolean; cdecl; external 'matr_dll.dll';
 
{*************** .......................... libmx.dll ****************}
{9} function mxCreateDoubleMatrix(m,n:Integer;mxData:mxComplexty):pmxArray; cdecl; external 'libmx.dll';
{10}procedure mxSetName(arr_ptr:pmxArray; const name:String);cdecl; external 'libmx.dll';
{11}function mxGetPr(arr_ptr:pmxArray):pDouble;cdecl; external 'libmx.dll';
{12}function mxGetPi(arr_ptr:pmxArray):pDouble;cdecl; external 'libmx.dll';
{13}procedure mxDestroyArray(arr_ptr:pmxArray); cdecl; external 'libmx.dll';
{14}procedure mxFree(var ram:THandle); cdecl; external 'libmx.dll';
{15}function mxTranspose(x:pmxArray):pmxArray; cdecl; external 'libmx.dll';
{*************** .......................... mclmcr.dll ****************}
{16}function mclInitializeApplication(A:THandle;B:Integer):Boolean;cdecl; external 'mclmcr.dll';
{17}function mclTerminateApplication:Boolean; cdecl; external 'mclmcr.dll';
 
 
var
  Form1: TForm1;
  Flag_MCR_Initialize : Boolean = False;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var A,B,C: pmxArray;
begin
  GetMem(A,sizeof(mxArray));
  GetMem(B,sizeof(mxArray));
//  A^:=1;
//  B^:=2;
  if Flag_MCR_Initialize=False then
  begin
{   mclInitializeApplication(0,0);
   _matr_dllInitialize; {}
  end;
  A := mxCreateDoubleMatrix(1, 1, mxREAL);
  B := mxCreateDoubleMatrix(1, 1, mxREAL);
  C:= nil;
  _mlfPlusvak(1,C,A,B);
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  mclInitializeApplication(0,0);
//  _matr_dllInitialize;
end;
 
end.
Миниатюры
Matlab dll и Delphi  
0
132 / 129 / 31
Регистрация: 12.12.2011
Сообщений: 462
14.02.2012, 17:14
Цитата Сообщение от acrost Посмотреть сообщение
Подскажите пожалуйста, как это сделать?
На Windows XP нужно правой мыши по "Мой компьютер"-Свойства-Переменные среды. В системных переменных есть параметр "path". Жмем изменить.Там лежит много всего, параметры разделены знаком ";". Главное найти пути, которые ведут к установленному MatLab и ПЕРЕД ними вставить пути, ведущие к директории где установлен MCR.
И еще, у Вас названия функций начинаются с "_". Проверьте это, поскольку у меня название начинаются просто с mlf. Советую просмотреть созданную dll утилиткой Depends.

Добавлено через 52 минуты
Вот еще код приложения, которое решает систему F(x) = 0, беря ее из текстового файла, а начальные приближения задаются вручную.
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
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Unit2;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
   if Unit2.Solver11Initialize() then
   Application.MessageBox('Good!','Initialized',MB_OK+MB_ICONINFORMATION)
   else
   Application.MessageBox('Fail!',' Not initialized',MB_OK+MB_ICONERROR);
end;
 
procedure TForm1.Button3Click(Sender: TObject);
begin
   Close();
end;
 
procedure TForm1.Button2Click(Sender: TObject);
var A,B:array of Double;
    AA,BB,CC:pmxArray;
    i:Integer;
    St:String;
begin
   //Ïèøåì óðàâíåíèÿ â ôàéë Solver.txt
   Memo1.Lines.SaveToFile('Solver.txt');
 
   //Âåêòîð íà÷àëüíûõ ïðèáëèæåíèé è ðåçóëüòàòîâ:
   SetLength(A,Memo2.Lines.Count);
   SetLength(B,Memo2.Lines.Count);
   for i:=0 to Memo2.Lines.Count-1 do
   begin
      A[i]:=StrToFloat(Memo2.Lines.Strings[i]);
   end;
 
   AA:=mxCreateDoubleMatrix(1,Length(A),mxReal);
   Move(A[0],mxGetPr(AA)^,Length(A)*SizeOf(Double));
 
   BB:=nil; CC:=nil;
 
   mlfSolver11(2,BB,CC,AA);
 
   Move(mxGetPr(BB)^,B[0],Length(A)*SizeOf(Double));
   St:='';
   for i:=0 to Length(B)-1 do
   begin
      St:=St+FormatFloat('0.0000',B[i]);
      if i<Length(B)-1 then
      St:=St+#$A;
   end;
 
   ShowMessage(St);
 
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
   if FileExists('Solver.txt') then
   Memo1.Lines.LoadFromFile('Solver.txt');
end;
 
end.
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
unit Unit2;
 
interface
 
type
    pDouble = ^Double;
    mxComplexty = (mxREAL, mxCOMPLEX);
    pmxArray = ^mxArray;
    mxArray = record end;
    pString = ^String;
 
//Libmx.dll
function mxCreateDoubleMatrix(m,n:Integer;mxData:mxComplexty):pmxArray; cdecl;
function mxGetPr(arr_ptr:pmxArray):pDouble; cdecl;
function mxGetPi(arr_ptr:pmxArray):pDouble;cdecl;
function mxTranspose(x:pmxArray):pmxArray; cdecl;
procedure mxDestroyArray(arr_ptr:pmxArray); cdecl;
//===
function mxCreateString(S:String):pString; cdecl;
 
function Solver11Initialize():Boolean; cdecl; external 'Solver11.dll';
 
procedure mlfSolver11(i:Integer; var poutX:pmxArray; var poutFVal:pmxArray;  N:pmxArray); cdecl; external 'Solver11.dll';
 
implementation
 
function mxCreateDoubleMatrix; external 'libmx.dll' name 'mxCreateDoubleMatrix';
function mxGetPr; external 'libmx.dll' name 'mxGetPr';
function mxGetPi; external 'libmx.dll' name 'mxGetPi';
function mxTranspose; external 'libmx.dll' name 'mxTranspose';
procedure mxDestroyArray; external 'libmx.dll' name 'mxDestroyArray';
 
//===
function mxCreateString; external 'libmx.dll' name 'mxCreateString';
 
end.
2
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 8
15.02.2012, 12:33
Цитата Сообщение от Vabos Посмотреть сообщение
На Windows XP нужно правой мыши по "Мой компьютер"-Свойства-Переменные среды. В системных переменных есть параметр "path". Жмем изменить.Там лежит много всего, параметры разделены знаком ";". Главное найти пути, которые ведут к установленному MatLab и ПЕРЕД ними вставить пути, ведущие к директории где установлен MCR.
И еще, у Вас названия функций начинаются с "_". Проверьте это, поскольку у меня название начинаются просто с mlf. Советую просмотреть созданную dll утилиткой Depends.
Пути прописал. Не помогло. У меня стоял MATLAB R2008a.
На всякий случай, установил еще R2010b. MATLAB Compiler Runtime v714. Delphi 7 у меня.
Опишу порядок моих действий:

1. в Матлабе mbuild -setup
Select a compiler:
[1] Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2010b\sys\lcc
[2] Microsoft Visual C++ 6.0 in C:\Program Files\Microsoft Visual Studio

[0] None

Выбирал и тот и другой. В первом случае делает функции с приставкой "_", во втором без нее.

2. deploytool

Текст функции на матлабе выглядит так:
Delphi
1
2
function a = Plusvak(a1, a2)
a = a1 + a2;
Получаю my.dll - для Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2010b\sys\lcc и my2.dll - для Microsoft Visual C++ 6.0 in C:\Program Files\Microsoft Visual Studio.
Проверяю как называются в нем функции при помощи tdump или/и утилиты depends.

3. В Delphi изменил немного код (несущественно)

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
unit main;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
  type
    pDouble = ^Double;
    mxComplexty = (mxREAL, mxCOMPLEX);
    pmxArray = ^mxArray;
    mxArray = record end;
 
procedure mlfPlusvak(i:Integer; var pout:pmxArray; A,B:pmxArray);cdecl; external 'my2.dll';
procedure my2Initialize; cdecl; external 'my2.dll';
// procedure _myTerminate; cdecl; external 'testc.dll';
 
 
{*************** .......................... libmx.dll ****************}
{9} function mxCreateDoubleMatrix(m,n:Integer;mxData:mxComplexty):pmxArray; cdecl; external 'libmx.dll';
{10}procedure mxSetName(arr_ptr:pmxArray; const name:String);cdecl; external 'libmx.dll';
{11}function mxGetPr(arr_ptr:pmxArray):pDouble;cdecl; external 'libmx.dll';
{12}function mxGetPi(arr_ptr:pmxArray):pDouble;cdecl; external 'libmx.dll';
{13}procedure mxDestroyArray(arr_ptr:pmxArray); cdecl; external 'libmx.dll';
{14}procedure mxFree(var ram:THandle); cdecl; external 'libmx.dll';
{15}function mxTranspose(x:pmxArray):pmxArray; cdecl; external 'libmx.dll';
{*************** .......................... mclmcr.dll ****************}
{16}function mclInitializeApplication(A:THandle;B:Integer):Boolean;cdecl; external 'mclmcr.dll';
{17}function mclTerminateApplication:Boolean; cdecl; external 'mclmcr.dll';
 
 
var
  Form1: TForm1;
  Flag_MCR_Initialize : Boolean = False;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
const col = 1; row = 1;
var A,B,C: pmxArray;
    AMass,BMass,CMass: array[1..row,1..col] of Double;
    i,j: integer;
begin
  if not Flag_MCR_Initialize then
  begin
   mclInitializeApplication(0,0);
   my2Initialize;
   Flag_MCR_Initialize:=true;
  end;
  randomize;
  for i:=1 to row do
  for j:=1 to col do
  begin
   AMass[i,j]:=random(10)+1;
   BMass[i,j]:=random(10)+1;
  end;
  A := mxCreateDoubleMatrix(row, col, mxREAL);
  Move(AMass, mxGetPr(A)^, row*col*sizeof(double));
  A:=mxTranspose(A);
  B := mxCreateDoubleMatrix(row, col, mxREAL);
  Move(BMass, mxGetPr(B)^, row*col*sizeof(double));
  B:=mxTranspose(B);
  C:=nil;
  i:=StrToInt(Edit1.Text);
  mlfPlusvak(i,C,A,B);
  if C<>nil then
  begin
   C:=mxTranspose(C);
   Move(mxGetPr(C)^, CMass, row*col*sizeof(double));
   ShowMessage('Успешно!');
  end;
end;
 
end.


Edit1 - сделал для изменения первого параметра в mlfPlusvak. Думал что может от него чтото зависит.
Проблема:
Программа не вылетает, но с переменной C ничего не происходит!
Она как была nil до вызова mlfPlusvak(i,C,A,B); так nil и остается.

Помогите разобраться что делаю не так?
В прикрепленном файле dll_matlab_delphi.rar (528.0 Кб) :
- проект Delphi
- два файла my.dll и my2.dll
- файл функции Plusvak.m

И, если не сложно, не могли бы вы выложить вами "скомпилированный" dll этой функции и проект delphi, чтобы можно было в нем посмотреть и файл dll тоже глянуть.

ps. самое странное, что при создании dll, он получается разных размеров. вначале они у меня были по 600-700 кбайт. последние два что я сделал получились по ~80-90 кбайт.
Вложения
Тип файла: rar dll_matlab_delphi.rar (528.0 Кб, 156 просмотров)
0
132 / 129 / 31
Регистрация: 12.12.2011
Сообщений: 462
15.02.2012, 15:50
У Вас в папке проекта Dephi находятся два файла: libmx.dll и mclmcr.dll, чего быть не должно. Эти же файлы лежат в директории, куда ставился MCR. Собственно для этого и прописывались пути, чтобы Ваше приложение не найдя в текущей директории нужные dll начало их искать по системным путям. А пути-то как раз ведут к MCR, где есть все нужные dll-ки. В директории экзэшника нужно оставить только свою dll.
Я запускал ваш проект, только убрал строку "mclInitializeApplication(0,0);" и еще убрал из проекта какой-то Unit. Все работает замечательно. Вместо nil появляется значение.
Миниатюры
Matlab dll и Delphi  
1
132 / 129 / 31
Регистрация: 12.12.2011
Сообщений: 462
15.02.2012, 16:08
Вот еще архивчик с dll-кой
Вложения
Тип файла: rar DepProject.rar (162.8 Кб, 186 просмотров)
1
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 8
17.02.2012, 14:18
Цитата Сообщение от Vabos Посмотреть сообщение
У Вас в папке проекта Dephi находятся два файла: libmx.dll и mclmcr.dll, чего быть не должно. Эти же файлы лежат в директории, куда ставился MCR. Собственно для этого и прописывались пути, чтобы Ваше приложение не найдя в текущей директории нужные dll начало их искать по системным путям. А пути-то как раз ведут к MCR, где есть все нужные dll-ки. В директории экзэшника нужно оставить только свою dll.
Я запускал ваш проект, только убрал строку "mclInitializeApplication(0,0);" и еще убрал из проекта какой-то Unit. Все работает замечательно. Вместо nil появляется значение.
Сам не знаю как, но мне удалось что заработало. Удалил R2008a матлаб. Переписал по новой path.
Просмотрел файлы mclmcr.dll.
В версии 7.14 действительно нет mclInitializeApplication, а в версии 7.8 - есть.
Стал искать аналогичную функцию, потому что без нее, у меня почему то ничего не работало.
нашел вот такую - mclmcrInitialize и запустил ее. И о чудо, всё заработало. Смеха ради закомментировал ее и тоже все работало и без нее. Кароче чудеса какие то. Суть в том, что покрайней мере стало работать. Спасибо вам за помощь =)

Теперь встал другой вопрос, почему то выполнении dll процедур матлабовских в дельфи медленней примерно раз в 5 чем в самом матлабе :o
Проверял на Фурье fft и еще одной. Причем опять "очевидное невероятное" = если запустить процедуру второй раз, третий ... то время уменьшается, до какого то приемлемого значения.
Вот сделал небольшую программку


Матлабовская функция
Delphi
1
2
3
4
5
6
7
x=1:100;
y=sin(x);
x=x./y;
y=sin(x);
tic
[a,b]=dst1(y,1);
toc
сама функция (на примере просчет для nn=2, т.е. для Фурье)
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
function [out,nimf] = dst1(y,nn)
if nn==1 % HHT
    options.maxmodes = inf;
    out=emd(y,options);
    nimf=size(out,1);
end
if nn==2 % FFT
    L=max(size(y));
    NFFT = 2^nextpow2(L); % Next power of 2 from length of y
    out = fft(y,NFFT)/L;
    nimf=L;
end
end
Матлаб на моей машине справляется с этим кодом за
Elapsed time is 0.004518 seconds.
или другими словами 4,518 мсек

Дельфи же требуется при первом вызове процедуры 88 мсек, при втором 10,67 мсек; и при третьем уже 0,65 мсек.

Время засекаю только на работу самой процедуры dst1. Т.е. всякая инициализация, подготовка данных и т.д. не считаются. Как бы мне сразу получать время на выполнение процедуры, а не в третий раз? Я думал что дельфи наоборот быстрей должно обрабатывать чем матлаб.

На всякий случай добавил архив с проектом и dll.
Вложения
Тип файла: rar matlab_delphi_test_speed.rar (245.8 Кб, 147 просмотров)
0
132 / 129 / 31
Регистрация: 12.12.2011
Сообщений: 462
20.02.2012, 16:07
У себя наблюдаю такую же картину =)
Если честно, то не знаю, чем это может быть вызвано.
На мой взгляд, первый долгий вызов dll долгий объясняется тем, что сначала инициализируется созданная dll и часть необходимых ресурсов, а не ресурсы на которые она потом будет ссылаться, т.е. другие dll-ки. Повторная инициализация dll происходит почти мгновенно. А с первым запуском расчета должна быть та же самая картина. Первый запуск долгий, а потом время выполнения практически такое же, как в матлабе. Может быть это связанно с работой MCR, что она динамически что-то подгружает. Расшифровывается-то как Matlab Component Runtime. Там в статье, ссылку на которую я выше выкладывал, что-то было про функционирование этой среды. Думаю, что Runtime здесь ключевое слово, которое и объясняет это странное поведение. В любом случае, это черный ящик, залезть в который не представляется возможным.
На всякий случай выкладываю свой проект, который решает систему уравнений. Может пригодится. У меня первая инициализация проходит примерно за 6 сек., потом <1 cек. Первый расчет также примерно 6-7 сек., потом занимает ~1-2 сек.
Вложения
Тип файла: rar SOLVE.rar (1,010.1 Кб, 130 просмотров)
0
0 / 0 / 0
Регистрация: 20.03.2013
Сообщений: 14
20.03.2013, 11:28
Добрый день, помогите. Пытаюсь сделать, что у вас уже получилось... Установил mcr 7.14 , запускаю exe solver - не запускается , пишет "Запуск программы невозможен, так как на компьютере отсутствует libmx.dll. "
У меня windows 7 , пути прописал... Что может быть?

Добавлено через 16 минут
Вопрос снимается, моя ошибка. Неправильно переменные среды прописал. Буду пытаться явно библиотеки указывать.
Надо тему продолжать, многие тулбоксы можно использовать))
0
132 / 129 / 31
Регистрация: 12.12.2011
Сообщений: 462
20.03.2013, 12:41
Я пытался с этим разобраться, когда искал считалку для своей задачи. После многих попыток и неудач наткнулся на библиотечку Intel MKL (Math Kernel Library). Хоть она и написана для C++ но из Delphi ее тоже просто использовать. Поэтому я забил на матлаб, сейчас использую MKL проблем нет.
0
0 / 0 / 0
Регистрация: 20.03.2013
Сообщений: 14
20.03.2013, 13:52
Интересно.. надо будет посмотреть. Мне нужен только fuzzy logic toolbox из целого матлаба. Нигде не встречался?
0
132 / 129 / 31
Регистрация: 12.12.2011
Сообщений: 462
20.03.2013, 16:36
Нет, не встречался.
0
0 / 0 / 0
Регистрация: 05.06.2015
Сообщений: 1
05.06.2015, 18:45
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function d = Edges (path)
clear;
J = imread('cap1.bmp');
I = rgb2gray(J);
BW1=edge(I,'sobel');
figure,imshow(BW1);title('sobel');
BW2=edge(I,'prewitt');
figure,imshow(BW2);title('prewitt');
BW3=edge(I,'roberts');
figure,imshow(BW3);title('roberts');
BW4=edge(I,'log');
figure,imshow(BW4);title('log');
BW5=edge(I,'zerocross');
figure,imshow(BW5);title('zerocross');
BW6=edge(I,'canny');
figure,imshow(BW6);title('canny');
d=1;
В Матлабе исполняется без проблем. Делаю из него библиотеку, как описано выше. Пути прописаны.
Объявляю у себя в программе на Делфи

Delphi
1
2
3
4
5
6
7
  {*************** .......................... mclmcr.dll ****************}
    function mclInitializeApplication(A:THandle;B:Integer):Boolean; cdecl; external 'mclmcr.dll';
    function mclTerminateApplication:Boolean; cdecl; external 'mclmcr.dll';
{******** ........ dll-.................... Untitled1.dll .................... Matlab *******}
    function _Untitled1Initialize:Boolean; cdecl; external 'Untitled1.dll';
    function _Untitled1Terminate :Boolean; cdecl; external 'Untitled1.dll';
    procedure _mlfEdges(i:Integer; var d1:integer; d2:integer); cdecl; external 'Untitled1.dll';
Вызываю нажатием кнопки

Delphi
1
2
3
4
5
6
7
8
procedure TMainForm.ComputeButtonClick(Sender: TObject);
var
  d1,d2:integer;
begin
  d1:=1;
  d2:=1;
  _mlfEdges(1,d1,d2);
end;
Получаю
---------------------------
Debugger Fault Notification
---------------------------
Project C:\Documents and Settings\Ôåññ\Ðàáî÷èé ñòîë\Íîâàÿ ïàïêà\Ïðîãðàììà\Diplom.exe faulted with message: 'access violation at 0x7ba0d701: read of address 0x00000019'. Process Stopped. Use Step or Run to continue.
---------------------------
OK
---------------------------
Что я делаю не так?
0
0 / 0 / 0
Регистрация: 03.08.2015
Сообщений: 4
10.01.2016, 22:38
Ребят, спасибо огромное - хоть что-то понял. Только одно смущает - у меня матлаб 2015b и делфи xe3 sp2. Так вот при запуске кода выдает "Точка входа в процедуру mxTranspose не найдена в библиотеке DLL", причем, зараза, даже не указывает в какой. Объявлена как и в примерах выше - function mxTranspose; external 'libmx.dll' name 'mxTranspose'; На остальные ф-ции не ругается - только на транспорирование. А без него - "NIL" и все ты тут. Кто поможет советом?
0
0 / 0 / 0
Регистрация: 14.05.2015
Сообщений: 1
30.06.2016, 08:55
помогите написать программку для решения системы нелинейных уравнений в matlab. которую можно вызвать через delphi. пожалуйста
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
30.06.2016, 08:55
Помогаю со студенческими работами здесь

Inline-функции Matlab + Delphi
Всех с наступающим!:drink: Кто-нибудь знает как передать inline функции параметры для подстановки в виде массива? Суть в том, чтобы...

Matlab Wavelet Morlet для Delphi
Добрый день, уважаемые форумчане! У меня следующая проблема. Я использовал в течение нескольких лет для своих научных расчетов Matlab...

Программа написано на Delphi провести на Matlab
Здравствуйте, помогите пожалуйста, провести программу из Delphi на Matlab чтобы ответ получился в графическом и численном виде. Очень...

Сортировка выбором,перевод кода из Delphi в Matlab
Помогите пожалуйста реализовать сортировку методом выбора в Matlabe Есть код из Delphi нужно перевести его в Matlab ...

можно ли в Matlab создать библиотеку для С++ и использовать ее без вызова Matlab?
Возможно ли с помощью команды deploytool или какой-то другой команды создать библиотеку .dll например функции polyxpoly, чтобы в...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru