Есть решение?
Модератор: Модераторы
-
Saemon Zixel
- новенький
- Сообщения: 78
- Зарегистрирован: 20.09.2005 18:19:54
- Откуда: Sochi
Код: Выделить всё
var a : integer;
b : integer absolute a;
begin
a := 10;
writeln(b);
end.Или надо чтобы во время исполнения присваивалось?
-
Saemon Zixel
- новенький
- Сообщения: 78
- Зарегистрирован: 20.09.2005 18:19:54
- Откуда: Sochi
Saemon Zixel,
напиши, КАК ты хочешь передавать параметры в библиотеку, и ЧТО именно сделать с ними (как использовать хочешь, хотя бы примерный код набросай, а то
напиши, КАК ты хочешь передавать параметры в библиотеку, и ЧТО именно сделать с ними (как использовать хочешь, хотя бы примерный код набросай, а то
как-то не совсем понятно для тех, кто НЕ пишет программу вместе с тобой), а потом уже будем говорить, может это FreePascal или нет... <_<чтобы не вставлять теперь везде ^ я хотел сменить указатели переменных на переданные массивы
-
Saemon Zixel
- новенький
- Сообщения: 78
- Зарегистрирован: 20.09.2005 18:19:54
- Откуда: Sochi
library test;
var a: array [1..100] as integer;
procedure test(p: pointer); cdecl; export;
begin
@a:=p;
end;
function test2: integer; cdecl; export;
begin
result:=a[1];
end;
exports test;
exports test2;
end.
//-----------------------------------------
program testing;
interface
var
procedure test(p: pointer); external 'libtest.so';
function test2:integer; external 'libtest.so';
t: array [1..100] as integer;
i: integer;
implementation
begin
for i:=1 to 100 do t[i]:=i;
test(@t);
if test2 = 1 then writeln('ok') else writeln('err');
end;
Гдето вот так должно это быть.
Массив создаётся в программе и передаётся только адрес массива.В библеотеке у существующей переменной меняется адресс на 200байт в сегменте данных вызывающей программы, и библеотека делает с этими данными что хочет...
В принципе можно написать export в конце второй строчки и не напрягатся, но у меня появляются проблемы с динамическими массивами.
PS кстати программа при завершении работы выдаёт окошко 'Project raised exception class 'External: SIGSEGV'', а в кансоли
EAccessViolation :
An unhandled exception occurred at $00000000 :
бесконечно. случаем не знаеш из-за чего?
var a: array [1..100] as integer;
procedure test(p: pointer); cdecl; export;
begin
@a:=p;
end;
function test2: integer; cdecl; export;
begin
result:=a[1];
end;
exports test;
exports test2;
end.
//-----------------------------------------
program testing;
interface
var
procedure test(p: pointer); external 'libtest.so';
function test2:integer; external 'libtest.so';
t: array [1..100] as integer;
i: integer;
implementation
begin
for i:=1 to 100 do t[i]:=i;
test(@t);
if test2 = 1 then writeln('ok') else writeln('err');
end;
Гдето вот так должно это быть.
Массив создаётся в программе и передаётся только адрес массива.В библеотеке у существующей переменной меняется адресс на 200байт в сегменте данных вызывающей программы, и библеотека делает с этими данными что хочет...
В принципе можно написать export в конце второй строчки и не напрягатся, но у меня появляются проблемы с динамическими массивами.
PS кстати программа при завершении работы выдаёт окошко 'Project raised exception class 'External: SIGSEGV'', а в кансоли
EAccessViolation :
An unhandled exception occurred at $00000000 :
бесконечно. случаем не знаеш из-за чего?
>>procedure test(p: pointer); cdecl; export;
>>begin
>>@a:=p;
>>end;
нет, так не выйдет
>>var a: array [1..100] as integer;
массив создается на стадии компиляции и его адрес ты никак не изменишь
ты определил 2 массива 1 в программе, другой в библиотеке
будет работать чтонить вроде:
library test;
type arr=array [1..100] as integer;
...
function test2(var b:arr): integer; cdecl; export;
begin
result:=b[1];
end;
...
при этом ты неявно передаешь в библиотеку указатель на массив созданый в программе
>>begin
>>@a:=p;
>>end;
>>var a: array [1..100] as integer;
массив создается на стадии компиляции и его адрес ты никак не изменишь
ты определил 2 массива 1 в программе, другой в библиотеке
будет работать чтонить вроде:
library test;
type arr=array [1..100] as integer;
...
function test2(var b:arr): integer; cdecl; export;
begin
result:=b[1];
end;
...
при этом ты неявно передаешь в библиотеку указатель на массив созданый в программе
-
Saemon Zixel
- новенький
- Сообщения: 78
- Зарегистрирован: 20.09.2005 18:19:54
- Откуда: Sochi
zub писал(а):library test;
type arr=array [1..100] as integer;
...
function test2(var b:arr): integer; cdecl; export;
begin
result:=b[1];
end;
Да, но когда test2 закончится к b уже нельзя будет достучатся!
Ну хорошо я напишу в начале так
library test;
var
arr: array as integer;
...
и он создастся в куче и будет динамическим, можно будет сменить адрес?
PS Кстати это правда что кача у fpc динамически может растягиватся на всю доступную память компа?
-
Saemon Zixel
- новенький
- Сообщения: 78
- Зарегистрирован: 20.09.2005 18:19:54
- Откуда: Sochi
>>Да, но когда test2 закончится к b уже нельзя будет достучатся!
можещ сохранить @b в переменной ba:^arr и потом обращаться как ba^[i]...
но так дучше не делать, особенно в библиотеке
>>и он создастся в куче и будет динамическим, можно будет сменить адрес?
что ты подразумеваешь под сменить адрес объекта? я подразумеваю выделить память под объект, скопировать его туда, удалить старый, исправить в программе все ссылки на обект (что невозможно если ты не создаешь объект сам и не хранищь его адрес в переменной через которую к нему и обращаешся)
>>PS Кстати это правда что кача у fpc динамически может растягиватся на всю доступную память компа?
истинная:)
можещ сохранить @b в переменной ba:^arr и потом обращаться как ba^[i]...
но так дучше не делать, особенно в библиотеке
>>и он создастся в куче и будет динамическим, можно будет сменить адрес?
что ты подразумеваешь под сменить адрес объекта? я подразумеваю выделить память под объект, скопировать его туда, удалить старый, исправить в программе все ссылки на обект (что невозможно если ты не создаешь объект сам и не хранищь его адрес в переменной через которую к нему и обращаешся)
>>PS Кстати это правда что кача у fpc динамически может растягиватся на всю доступную память компа?
истинная:)
-
SovNarKom
- постоялец
- Сообщения: 389
- Зарегистрирован: 28.05.2005 10:37:39
- Откуда: Воронеж [vrn] [36]
- Контактная информация:
Saemon Zixel
В общем есть такие понятия как передача переменной по ссылке и по значению... вот тебе нужен первый вариант как я понимаю.
То есть тебе нужно передавать в библиотеку указатель на массив
>Да, но когда test2 закончится к b уже нельзя будет достучатся!
А смысл? Этож модульное программирование... Если нужно именно подставлять указатель - работай как делал с ^.
По-другому нельзя никак и нигде.
Единственно - попробовать передавать класс, в котором будет массив.
(но это жутко извратно)
По поводу ошибок - читай про SetMemoryManager (на этом сайте есть).
В общем есть такие понятия как передача переменной по ссылке и по значению... вот тебе нужен первый вариант как я понимаю.
То есть тебе нужно передавать в библиотеку указатель на массив
>Да, но когда test2 закончится к b уже нельзя будет достучатся!
А смысл? Этож модульное программирование... Если нужно именно подставлять указатель - работай как делал с ^.
По-другому нельзя никак и нигде.
Единственно - попробовать передавать класс, в котором будет массив.
(но это жутко извратно)
По поводу ошибок - читай про SetMemoryManager (на этом сайте есть).
-
Saemon Zixel
- новенький
- Сообщения: 78
- Зарегистрирован: 20.09.2005 18:19:54
- Откуда: Sochi
Спасиба за содержательные ответы.
Ситуацию я разрулил дописав export; в библеотеке и external; в программе, получилось как надо.
Но возникла ещё более сложная проблема, не получается воcпользоватся функцией переданой по указателю, вылетает по Access Violution (программа).
Пример:
Никак не пойму, как правельно cделать.
PS Из летературы есть только учебник по TP5.5 :unsure:
Ситуацию я разрулил дописав export; в библеотеке и external; в программе, получилось как надо.
Но возникла ещё более сложная проблема, не получается воcпользоватся функцией переданой по указателю, вылетает по Access Violution (программа).
Пример:
Код: Выделить всё
library test;
type PGetStr = function (indx: integer): string;
var GetStr: PGetStr; export;
function test(p: pointer; flag: boolean):string; cdecl;
begin
if flag then pointer(GetStr):=p;
result:= GetStr(1);
end;
exports test;
end.
//-------------------------------
program testing;
interface
type PGetStr = function (indx: integer): string;
var ExGetStr: PGetStr; external name 'GetStr';
function test(p: pointer; flag: boolean):string; cdecl; external 'libtest.so';
implementation
{$F+}
function GetStr(indx: integer): string;
begin
result:=IntToStr(indx);
end;
{$F-}
begin
writeln(test(@GetStr,true));
//или так
ExGetStr:=@GetStr;
writeln(test(nil,false));
end.
Никак не пойму, как правельно cделать.
PS Из летературы есть только учебник по TP5.5 :unsure:
-
Saemon Zixel
- новенький
- Сообщения: 78
- Зарегистрирован: 20.09.2005 18:19:54
- Откуда: Sochi
После отката на fpc2.0.0 и Lazarus 0.9.12 вариант с ExGetStr:=@GetStr заработал нормально
.
Но теперь я зашол в полный тупик
.
Ну хорошо поставлю я string[256]; не в этом дело.
Я хотел чтоб библеотека, когда ей понадобится, вызываля функцию в программе с запросом нужной строки.
Примерно...
Всё так хорошо было, а теперь оказалось что вызываемая библеотекой функция GetStr в программе выполняется в контексте библеотеки и о FileWithStrings обьекте ничего не знает
. После долгих раздумий (~2часа) и поиска в гугле (~3 часа) я понял что если неполучится менять контекст на программный при вызове, то придётся переробатывать много строчек кода в библеотеке и менять логику многих функций <_< , а это очень плохо.
PS Вот-так меня кинул этот fp <_<
PSS Кстати откапал какойто термин - "callback", он может отнасится к моей проблеме?
Но теперь я зашол в полный тупик
Стринги нельзя передавать из dll в ехе или что там в линуксе. переменная типа string - динамический массив, должен убиваться или изменяться в томже модуле где создан.
Ну хорошо поставлю я string[256]; не в этом дело.
Чето ты какието сложности наводишь на пустом месте скажи конкретно что ты хочешь получить?
Я хотел чтоб библеотека, когда ей понадобится, вызываля функцию в программе с запросом нужной строки.
Примерно...
Код: Выделить всё
library test;
type PGetStr = function (indx: integer): string;
var GetStr: PGetStr; export;
procedure test; cdecl;
var i: integer;
begin
for i:= 1 to 22 do writeln(GetStr(i));
end;
exports test;
end.
//-------------------------------
program testing;
uses Classes;
interface
type
PGetStr = function (indx: integer): string;
var
ExGetStr: PGetStr; external name 'GetStr';
FileWithStrings: TStringList;
implementation
function GetStr(indx: integer): string;
begin
result:=FileWithString.Strings[indx];
end;
begin
FileWithStrings:=TStringLisr.Create;
FileWithStrings.LoadFromFile('testing.pas');
ExGetStr:=@GetStr;
test;
FileWithStrings.Free;
end.
Всё так хорошо было, а теперь оказалось что вызываемая библеотекой функция GetStr в программе выполняется в контексте библеотеки и о FileWithStrings обьекте ничего не знает
PS Вот-так меня кинул этот fp <_<
PSS Кстати откапал какойто термин - "callback", он может отнасится к моей проблеме?
