Вверх ↑
Этот топик читают: Гость
Ответов: 176
Рейтинг: 12
#16: 2011-09-03 11:48:14 ЛС | профиль | цитата
Ivann писал(а):
Ты её сначала в переменную запихни

Не помогло. Остался тот же результат.


Add(MainForm,2953706,98,84)
{
Width=572
}
Add(InlineCode,7294639,189,350)
{
@Hint=#45:Вызов функции SharedStrVarGet из HiAsmMQL.dll|
WorkPoints=#66:doSharedStrVarGet=Вызывает функцию SharedStrVarGet из HiAsmMQL.dll|
EventPoints=#61:onSharedStrVarGet=Выдаёт в поток результат выполнения функции|
DataPoints=#34:Ind=Индекс выбора общей переменной|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|21: _prop_Ind:integer;|37: Ind, onSharedStrVarGet: THI_Event;|60: Procedure doSharedStrVarGet(var _Data:TData; Index:Word);|0:|5: end;|1: |76:function SharedStrVarGet(i:integer):PChar; stdcall; external 'HiAsmMQL.dll';|0:|14:implementation|0:|40:Procedure THiAsmClass.doSharedStrVarGet;|3:var|12: i:integer;|13: out:string;|0:|5:begin|29: i:= readinteger(_Data,Ind);|35: out:= String(SharedStrVarGet(i));|37: _hi_OnEvent(onSharedStrVarGet,out);|4:end;|0:|4:end.|
link(onSharedStrVarGet,14192987:doMessage,[])
link(Ind,10818136:Value,[])
}
Add(Button,4595750,105,238)
{
Left=15
Top=40
Width=215
Caption="Отправить данные в общую переменную"
link(onClick,855798:doSharedStrVarSet,[])
}
Add(Message,14192987,252,350)
{
}
Add(Memory,10818136,189,301)
{
Default=Integer(0)
}
Add(InlineCode,855798,168,238)
{
@Hint=#45:Вызов функции SharedStrVarGet из HiAsmMQL.dll|
WorkPoints=#66:doSharedStrVarSet=Вызывает функцию SharedStrVarSet из HiAsmMQL.dll|
DataPoints=#36:InTxt=Строка, передаваемая в функцию|34:Ind=Индекс выбора общей переменной|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|22: _prop_InTxt:string;|21: _prop_Ind:integer;|25: InTxt, Ind: THI_Event;|60: Procedure doSharedStrVarSet(var _Data:TData; Index:Word);|0:|5: end;|1: |84:procedure SharedStrVarSet(InTxt:PChar; i:integer); stdcall; external 'HiAsmMQL.dll';|0:|14:implementation|0:|40:Procedure THiAsmClass.doSharedStrVarSet;|3:var|12: i:integer;|13: txt:string;|0:|5:begin|29: i:= ReadInteger(_Data,Ind);|37: txt:= ReadString(_Data,InTxt) + #0;|30: SharedStrVarSet(@txt[1], i);|4:end;|0:|4:end.|
link(InTxt,5629726:Text,[(174,222)(132,222)])
link(Ind,1358963:Value,[])
}
Add(Button,11769371,112,350)
{
Left=15
Top=70
Width=215
Caption="Получить данные из общей переменной"
link(onClick,7294639:doSharedStrVarGet,[])
}
Add(Memory,1358963,175,175)
{
Default=Integer(0)
}
Add(Label,8501754,175,84)
{
Left=15
Top=10
Width=221
Height=17
Caption="Функции SharedSteVarSet SharedSteVarGet"
}
Add(Button,10471125,392,217)
{
Left=15
Top=155
Width=215
Caption="Отправить данные в общую переменную"
link(onClick,206227:doSharedIntVarSet,[])
}
Add(Button,3568480,399,329)
{
Left=15
Top=185
Width=215
Caption="Получить данные из общей переменной"
link(onClick,2929720:doSharedIntVarGet,[])
}
Add(Label,1900393,462,84)
{
Left=15
Top=125
Width=213
Height=17
Caption="Функции SharedIntVarSet SharedIntVarGet"
}
Add(Memory,5491783,455,154)
{
Default=Integer(0)
}
Add(Memory,10680287,406,154)
{
Default=Integer(2030269057)
}
Add(InlineCode,2929720,455,329)
{
@Hint=#45:Вызов функции SharedStrVarGet из HiAsmMQL.dll|
WorkPoints=#66:doSharedIntVarGet=Вызывает функцию SharedStrVarGet из HiAsmMQL.dll|
EventPoints=#61:onSharedIntVarGet=Выдаёт в поток результат выполнения функции|
DataPoints=#34:Ind=Индекс выбора общей переменной|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|21: _prop_Ind:integer;|37: Ind, onSharedIntVarGet: THI_Event;|60: Procedure doSharedIntVarGet(var _Data:TData; Index:Word);|0:|5: end;|1: |78:function SharedIntVarGet(i:integer):integer; stdcall; external 'HiAsmMQL.dll';|0:|14:implementation|0:|40:Procedure THiAsmClass.doSharedIntVarGet;|3:var|12: i:integer;|14: out:integer;|0:|5:begin|29: i:= readinteger(_Data,Ind);|27: out:= SharedIntVarGet(i);|37: _hi_OnEvent(onSharedIntVarGet,out);|4:end;|0:|4:end.|
link(onSharedIntVarGet,11427307:doMessage,[])
link(Ind,13986349:Value,[])
}
Add(Message,11427307,518,329)
{
}
Add(Memory,13986349,455,280)
{
Default=Integer(0)
}
Add(InlineCode,206227,448,217)
{
@Hint=#45:Вызов функции SharedStrVarGet из HiAsmMQL.dll|
WorkPoints=#66:doSharedIntVarSet=Вызывает функцию SharedIntVarSet из HiAsmMQL.dll|
DataPoints=#36:InTxt=Строка, передаваемая в функцию|34:Ind=Индекс выбора общей переменной|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|22: _prop_InTxt:string;|21: _prop_Ind:integer;|25: InTxt, Ind: THI_Event;|60: Procedure doSharedIntVarSet(var _Data:TData; Index:Word);|0:|5: end;|1: |86:procedure SharedIntVarSet(InTxt:integer; i:integer); stdcall; external 'HiAsmMQL.dll';|0:|14:implementation|0:|40:Procedure THiAsmClass.doSharedIntVarSet;|3:var|12: i:integer;|14: txt:integer;|0:|5:begin|29: i:= ReadInteger(_Data,Ind);|33: txt:= ReadInteger(_Data,InTxt);|26: SharedIntVarSet(txt, i);|4:end;|0:|4:end.|
link(InTxt,10680287:Value,[(454,201)(412,201)])
link(Ind,5491783:Value,[])
}
Add(Edit,5629726,126,175)
{
Left=275
Top=35
Width=160
}

карма: 0
Время верстки: %cr_time% Текущее время: %time%
0
Ответов: 3349
Рейтинг: 233
#17: 2011-09-03 12:15:14 ЛС | профиль | цитата
У меня работает
карма: 1

0
Ответов: 176
Рейтинг: 12
#18: 2011-09-03 12:52:17 ЛС | профиль | цитата
Ivann, Скинь рабочий пример. Или это мой код работает?
карма: 0
Время верстки: %cr_time% Текущее время: %time%
0
Разработчик
Ответов: 26163
Рейтинг: 2127
#19: 2011-09-03 13:27:48 ЛС | профиль | цитата
Ivann писал(а):
Ты её сначала в переменную запихни

Есть небольшая неточность -- при добавлении нуля в конец происходит копирование строки, но и длина ее увеличивается на один, поэтому, нобходимо удалять после копирования последний символ, или обрезать строку, например -- SetLength(txt, Length(txt) - 1)
карма: 22

0
Ответов: 3349
Рейтинг: 233
#20: 2011-09-03 13:46:30 ЛС | профиль | цитата
Кстати, что интересно при передачи указателя Char, строка остается в памяти приложения, и при изменение Edit и последующем извлечении извлекается то что находиться в Edit
карма: 1

0
Ответов: 176
Рейтинг: 12
#21: 2011-09-04 00:20:12 ЛС | профиль | цитата
совершено верно. Ведь передается указатель. Но нужно, чтобы эти данные не изменялись при изменений edit
------------ Дoбавленo в 17.13:
Но у меня всё равно никак не работает. Даже если сначала запихнуть данные в стринговую переменную, а потом передать указатель на неё в dll...
Видео - http://forum.hiasm.com//getfile/25075
------------ Дoбавленo в 20.20:
Ура! Решено! Всётаки HiAsm победил в схватке. Переделал dll. Сделал, чтобы в общей памяти хранился не указатель на строку, а сама строка. Не хотелось добавлять в dll тип string, но пришлось. Может кому понадобится её код:

#include "stdafx.h"
#include <iostream>

#define MT4_EXPFUNC __declspec(dllexport)

using namespace std;

#pragma data_seg(".shared")
#pragma comment(linker,"/SECTION:.shared,RWS")
#pragma data_seg()
__declspec(allocate(".shared")) string SharedStrVar1, SharedStrVar2;
__declspec(allocate(".shared")) int SharedIntVar1, SharedIntVar2;

// Строковые переменные
MT4_EXPFUNC void __stdcall SharedStrVarSet(char *InTxt, int i)
{
string InStr;
InStr = InTxt;

switch(i)
{
case 0:
SharedStrVar1 = InStr;
break;
case 1:
SharedStrVar2 = InStr;
break;
}
}

MT4_EXPFUNC char* __stdcall SharedStrVarGet(int i)
{
std::string str1(SharedStrVar1);
std::string str2(SharedStrVar2);
char* s1 = new char[str1.length()+1]();
char* s2 = new char[str2.length()+1]();
strcpy(s1, str1.c_str());
strcpy(s2, str2.c_str());

char* out;
switch(i)
{
case 0:
out = s1;
break;
case 1:
out = s2;
break;
}
return (out);
}

// Переменные целых чисел
MT4_EXPFUNC void __stdcall SharedIntVarSet(int InInt, int i)
{
switch(i)
{
case 0:
SharedIntVar1 = InInt;
break;
case 1:
SharedIntVar2 = InInt;
break;
}
}

MT4_EXPFUNC int __stdcall SharedIntVarGet(int i)
{
int out;
switch(i)
{
case 0:
out = SharedIntVar1;
break;
case 1:
out =SharedIntVar2;
break;
}
return out;
}
------------ Дoбавленo в 20.35:
А вот и ролик, демонстрирующий работу Shared переменных. Через общую dll данные в переменных доступны из разных процессов. Чтобы общие переменные работали, нужно копировать dll в windows/system32
funccallsharelvar.rar
------------ Дoбавленo в 00.20:
Рано радуюсь. С короткими строками всё заработало, а вот длинные приводят к ран тайм еррору. Вычитал вот это:

[offtop]Общий менеджер памяти

Если выделение и освобождение динамической памяти явно или неявно поделены между библиотекой и программой, то и в библиотеке, и в программе следует обязательно подключить модуль ShareMem. Его нужно указать в секции uses первым, причем как в библиотеке, так и в использующей ее программе.

Модуль ShareMem является модулем импорта динамически загружаемой библиотеки Borlndmm.dll, которая должна распространяться вместе с вашей программой. В момент инициализации модуль ShareMem выполняет подмену стандартного менеджера памяти на менеджер памяти из библиотеки Borlndmm.dll. Благодаря этому библиотека и программа могут выделять и освобождать память совместно.

Модуль ShareMem следует подключать еще и в том случае, если между библиотекой и программой происходит передача длинных строк или динамических массивов. Поскольку длинные строки и динамические массивы размещаются в динамической памяти и управляются автоматически (путем подсчета количества ссылок), то блоки памяти для них, выделяемые программой, могут освобождаться библиотекой (а также наоборот). Использование единого менеджера памяти из библиотеки Borlndmm.dll избавляет программу и библиотеку от скрытых разрушений памяти.[/offtop]

Прописал в IC в секции uses ShareMem, теперь компилятор требует файл ShareMem.dcu. Искал на просторах интернета, не могу найти, где скачать. Может у кого завалялся?
карма: 0
Время верстки: %cr_time% Текущее время: %time%
0
файлы: 2callfuncvideo2.rar [3MB] [266], funccallsharelvar.rar [2.3MB] [174]
Ответов: 3349
Рейтинг: 233
#22: 2011-09-05 14:39:15 ЛС | профиль | цитата
toropchin, Передавай указатель на первый байт, и длину строки, после чего скопируй её в память dll, после чего внутри приложения она может быть освобождена
карма: 1

0
Ответов: 4631
Рейтинг: 749
#23: 2011-09-05 14:47:29 ЛС | профиль | цитата
Наверное, всё-таки, требуется ShareMem.pas. Скорей всего при портировании захочет ещё некоторых модулей. Может в IC и в dll использовать явное выделение/уничтожение памяти (с помощю API-функций типа GlobalAlloc)?
карма: 26

0
Ответов: 176
Рейтинг: 12
#24: 2011-09-05 21:57:36 ЛС | профиль | цитата
Netspirit писал(а):
Наверное, всё-таки, требуется ShareMem

Скачал delphi 7, написал там программку с использованием ShareMem. Ничего не изменилось. Тот же результат. Единственное, программа перестала входить в штопор Run Time error
------------ Дoбавленo в 21.57:
Ivann писал(а):
Передавай указатель на первый байт, и длину строки, после чего скопируй её в память dll, после чего внутри приложения она может быть освобождена

Так и попробую...
карма: 0
Время верстки: %cr_time% Текущее время: %time%
0
Ответов: 176
Рейтинг: 12
#25: 2011-09-07 15:46:57 ЛС | профиль | цитата
Наконец-то вопрос решился. Вот код рабочей dll

#cpp
#include "stdafx.h"

#define MT4_EXPFUNC __declspec(dllexport)

using namespace std;

// Создаем разделяемую секцию.
#pragma data_seg(".shared")
#pragma comment(linker,"/SECTION:.shared,RWS")
#pragma data_seg()

// Максимальная длина строки, в символах.
int const MaxStringLength = 65535;

/* Статическая проверка (опционально)

static_assert(0 != MaxStringLength, "MaxStringLength cannot be 0.");

*/

// Выделяем буфер в разделяемой секции и заполняем его нулями.
// В буфере должно быть место для строки и завершающего нуля.
__declspec(allocate(".shared")) char SharedStrVar1[MaxStringLength + 1] = {0};
__declspec(allocate(".shared")) char SharedStrVar2[MaxStringLength + 1] = {0};
__declspec(allocate(".shared")) char SharedStrVar3[MaxStringLength + 1] = {0};



// Функция записи строки в разделяемый буфер.
void __stdcall SharedStrVarSet(char* InStr, int i)
{
// Учитываем ситуацию с переполнением буфера.
if (MaxStringLength < lstrlenA(InStr))
{
return;
}
// Копируем строку в буфер.
switch(i)
{
case(0):
lstrcpyA(SharedStrVar1, InStr);
break;
case(1):
lstrcpyA(SharedStrVar2, InStr);
break;
case(2):
lstrcpyA(SharedStrVar3, InStr);
break;
}
}


// Функция чтения строки из разделяемого буфера.
char* __stdcall SharedStrVarGet(int i)
{
char* out;
switch(i)
{
case(0):
out = SharedStrVar1;
break;
case(1):
out = SharedStrVar2;
break;
case(2):
out = SharedStrVar3;
break;
}
return out;
}

карма: 0
Время верстки: %cr_time% Текущее время: %time%
1
файлы: 1code_25101.txt [1.8KB] [208]
Голосовали:Aziz
25
Сообщение
...
Прикрепленные файлы
(файлы не залиты)