Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2012.04.29;
Скачать: [xml.tar.bz2];

Вниз

dll без менеджера памяти для передачи строк   Найти похожие ветки 

 
Gu   (2012-01-05 11:18) [0]

Если у кого есть время, проверьте плз, небольшую программку:

Дано:
1. dll, в ней юнит

unit DllUnit; interface

uses windows, sysutils;

Procedure GuPrcA(var p:PAnsiChar;const l:integer); StdCall;
Procedure GuPrcW(var p:PWideChar;const l:integer); StdCall;

Exports GuPrcA,GuPrcW;

implementation

procedure GuMes(s:string);
begin
MessageBox(0,pchar(s),"From dll",mb_iconinformation);
end;

Procedure GuPrcW(var p:PWideChar;const l:integer); // wide
var s:widestring;
begin
if (p=nil)or(l<1) then begin p:=nil;exit;end;
SetLength(s,trunc(l/sizeof(widechar)));Move(p^,Pointer(s)^,l);
gumes("l: "+inttostr(l)+", nl: "+inttostr(length(s))+#10+"-"+s+"-");
s:=widestring(Uppercase(s));Move(Pointer(s)^,p^,l);
end;

Procedure GuPrcA(var p:Pansichar;const l:integer); // ansi
var s:ansistring;
begin
if (p=nil)or(l<1) then begin p:=nil;exit;end;
SetLength(s,l);Move(p^,Pointer(s)^,l);
gumes("l: "+inttostr(l)+", nl: "+inttostr(length(s))+#10+"-"+s+"-");
s:=ansistring(AnsiUppercase(s));Move(Pointer(s)^,p^,l);
end;

Initialization

ReportMemoryLeaksOnShutdown:=true;

end.


2. Прога, на окне мемо и 2 кнопки

...
implementation

{$R *.dfm}

Procedure GuPrcA(var p:PansiChar;const l:cardinal); StdCall; external "mydll.dll" name "GuPrcA";
Procedure GuPrcW(var p:PwideChar;const l:cardinal); StdCall; external "mydll.dll" name "GuPrcW";

procedure TForm1.Button6Click(Sender: TObject);
var p:pwidechar;c:cardinal;s:widestring;
begin
s:=widestring(memo1.Text);
c:=length(s)*sizeof(widechar);
p:=allocmem(c);
Move(Pointer(s)^,p^,c);
GuPrcW(p,c);
s:="";setlength(s,trunc(c/sizeof(widechar)));
Move(p^,Pointer(s)^,c);
Freemem(p,c);
memo1.Text:="="+s+"= l:"+inttostr(c);
end;

procedure TForm1.Button7Click(Sender: TObject);
var p:pansichar;c:cardinal;s:ansistring;
begin
s:=ansistring(memo1.text);
c:=length(s);
p:=allocmem(c);
Move(Pointer(s)^,p^,c);
GuPrcA(p,c);
s:="";setlength(s,c);
Move(p^,Pointer(s)^,c);
Freemem(p,c);
memo1.Text:="="+s+"= l:"+inttostr(c);
end;

Initialization

ReportMemoryLeaksOnShutdown:=true;

end.


исходник обоих (много зеркал): http://www.multiupload.com/WSZKF8IGP1

при нажатии на кнопки происходит передача в длл строки (ansi или wide), отображение ее в msgbox dll, обработка ее там (простой uppercase) и возврат в программу. Менеджер памяти не используется. И в проге и в dll включены ReportMemoryLeaksOnShutdown (отображение событий о потерях памяти), которые оба молчат, т.е. вроде бы все работает и длины строк тоже везде совпадают.

Что надо:
1. Посмотреть, нет ли там ошибок
2. Нельзя ли что-то оптимизировать или может есть какой способ лучше

Спасибо


 
Gu   (2012-01-05 11:23) [1]

Delphi Xe, забыл написать


 
RWolf ©   (2012-01-05 11:25) [2]

> trunc(l/sizeof(widechar))

В паскале это пишется так: l div sizeof(widechar).

Нельзя ли что-то оптимизировать

В программе неоправданно много ручных выделений/освобождений динамической памяти. Рекомендуется уменьшить до нуля.


 
Gu   (2012-01-05 11:45) [3]

так это.. без выделений памяти под p будут потери памяти. напишите пример, как лучше


 
Dimka Maslov ©   (2012-01-05 11:56) [4]

Бред написан. Полный бред. Так делать нельзя. Тут 95% лишнего кода.


 
RWolf ©   (2012-01-05 11:57) [5]


> без выделений памяти под p будут потери памяти.

не будет, временем жизни строк (читай: выделением/освобождением памяти) автоматически управляет менеджер памяти.


> напишите пример, как лучше


как-то так:


Procedure GuPrcW(p:PChar); // wide
var s:string;
begin
 if p=nil then exit;
 gumes("l: "+inttostr(l)+", nl: "+inttostr(length(p))+#10+"-"+p+"-");
 AnsiStrUpper(p);
end;

...

procedure TForm1.Button6Click(Sender: TObject);
var s:string;
begin
 s:=memo1.Text;
 if s<>"" then
   GuPrcW(s[1]);
 memo1.Text:="="+s+"= l:"+inttostr(c);
end;


предполагается, что передаваемые строки не содержат нулевых символов.


 
Gu   (2012-01-05 12:02) [6]

не не, необходимо в dll получить полноценную строку (особено wide), обработать ее (uppercase тут только для примера) и передать назад. там может быть и кодировка другая и тп - короче массив 2хбайтовых символов, где могут встречаться #0


 
_Юрий   (2012-01-05 12:07) [7]


> Gu   (05.01.12 12:02) [6]


> не не, необходимо в dll получить полноценную строку (особено
> wide)


Вайд-строки (в отличие от паскалевских) можно передавать прямо как есть, без всяких менеджеров памяти.


 
RWolf ©   (2012-01-05 12:07) [8]

ну ок, сохраним длину строки в параметрах, не принципиально.
суть в том, что, незачем выделять память вручную и перекладывать строки из одной в другую.


 
Gu   (2012-01-05 12:26) [9]


> Вайд-строки (в отличие от паскалевских) можно передавать
> прямо как есть, без всяких менеджеров памяти.

а можно по подробнее про это?
+ а анси?


> суть в том, что, незачем выделять память вручную и перекладывать
> строки из одной в другую.

на сколько я понял, строки передавать без манагеров нельзя, потому передаю через указатели. или не так?
задача какая: передать строку (анси или виде полноценную), обработать ее и вернуть назад: 1. без манагера памяти 2. совместимо должно быть желательно с Delphi, C++\C# и Vb


 
RWolf ©   (2012-01-05 12:53) [10]

proc GuPrcW(p:PChar; len:integer); для этого вполне подходит.


 
Gu   (2012-01-05 15:00) [11]

т.е. ещераз - GuPrcW подходит?
p.s. pchar теперь = pwidechar (Xe)

те, значит все правильно:
1. в дельфи (manager памяти не юзаем)
преобразуем строку(string(unicodestring),ansistring,widestring) в pwidechar
отправляем в длл ее и ее размер
преобразуем в widestring
делаем операции с ней
преобразуем обратно в pwidechar
отпрвляем в программу ее и ее размер
в проге получаем pwidechar и преобразуем в нужную строку(string(unicodestring),ansistring,widestring)
2. в C\Vb
передаем строку и размер
...
получаем строку и размер

все так?

и что там про

> Вайд-строки (в отличие от паскалевских) можно передавать
> прямо как есть, без всяких менеджеров памяти

?

Т.е. можно

Procedure GuPrcWW(var s:widestring;L:integer);
begin
GuMes(s);
s:=widestring(uppercase(s));
end;

? это будет работать корректно для C\Vb\Delphi Xe (без манагера памяти) без потерь и гимора? Тогда и длинна в принципе не нужна (L)?


 
RWolf ©   (2012-01-05 15:18) [12]


> т.е. ещераз - GuPrcW подходит?

я про параметры, а не про функцию.

не надо никаких преобразований, PChar совместим со string без преобразования, всё остальное, включая Ansi<->Unicode, преобразуется неявно.
в [5] всё это уже написано.


 
DVM ©   (2012-01-05 15:31) [13]


> всё остальное, включая Ansi<->Unicode, преобразуется неявно.

но возможно с потерей данных о чем компилятор сообщит в предупреждении


 
Gu   (2012-01-05 15:52) [14]

что-то както VB (VS 2010) криво работает при pchar

-------- Dll

Procedure GuPrcWSA(var s:pchar;const L:integer);
var n:string;
begin
GuMes(string(s)+" "+inttostr(l));
SetString(n,s,l);
n:=uppercase(n);
Move(Pointer(n)^,s^,l);
end;


-------------- VB

Public Declare Auto Sub GuPrcA Lib "c:\mydll.dll" Alias "GuPrcWSA" (ByVal ZZ As String, LL As Integer)
   
   Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
       Dim ZZ As String
       Dim mLL As Integer
       ZZ = "mama мылa mila ramu"
       mLL = Len(ZZ)
       GuPrcA(ZZ, mLL)
       Label1.Text = ZZ
   End Sub


запускается через раз, в сообщении строку не показывет, показывает только размер - 19 и обратно строку не передает. Кто VB знает, подскажите может там че не так пишу?


 
DVM ©   (2012-01-05 16:01) [15]

А в VB строки Wide или Ansi?


 
Gu   (2012-01-05 16:05) [16]

wide по умолчанию вроде. потому там при Public Declare Auto Sub можно вместо Auto написать Unicode (тоже не работает)


 
RWolf ©   (2012-01-05 16:05) [17]


> Gu   (05.01.12 15:52) [14]

типы параметров не согласованы.
ByVal — значит, в стек пойдёт указатель на 1-й символ строки.
А GuPrcWSA ожидает, что там будет указатель на указатель.
ну, и с stdcall надо бы прояснить — не знаю, как его писать в бейсике.


 
Gu   (2012-01-05 16:08) [18]

String: Содержит последовательности 16-битовых (2-байтовых) кодовых точек без знака со значениями в диапазоне от 0 до 65535.
Каждая кодовая точка, или код знака, представляет один символ Юникода.
Строка может содержать от нуля до приблизительно двух миллиардов (2^31) знаков Юникода.


 
Gu   (2012-01-05 16:10) [19]


> RWolf ©   (05.01.12 16:05) [17]

а как там по другому отметить, что это VAR перемення? т.е. отправить-получить?


 
Gu   (2012-01-05 16:12) [20]

не вроде все верно, byVal должно быть. Как тогда быть с pchar?


 
RWolf ©   (2012-01-05 16:12) [21]


> Gu   (05.01.12 16:10) [19]

здесь у ключевого слова var другой смысл.
это значит, что: 1) при вызове на стек будет положен адрес переменной, а не она сама, 2) по этому адресу можно записывать данные.


 
DVM ©   (2012-01-05 16:12) [22]


> Gu   (05.01.12 16:10) [19]


> а как там по другому отметить, что это VAR перемення? т.
> е. отправить-получить?

http://msdn.microsoft.com/ru-ru/library/ddck1z30.aspx


 
RWolf ©   (2012-01-05 16:13) [23]


> Gu   (05.01.12 16:12) [20]
> не вроде все верно, byVal должно быть. Как тогда быть с
> pchar?

я уже написал в [10].


 
Gu   (2012-01-05 16:18) [24]

ага заработало, заменил на ByRef
все всем спасибо



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2012.04.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.003 c
15-1325052694
Медвежонок Пятачок
2011-12-28 10:11
2012.04.29
Камень в огород (джава комьюнити)


15-1324549390
Раммер
2011-12-22 14:23
2012.04.29
Посоветуйте книжку по SQL.


15-1324626136
Gu
2011-12-23 11:42
2012.04.29
Пылесос


15-1324593730
alexdn
2011-12-23 02:42
2012.04.29
Open source проект


2-1325752586
Anthony
2012-01-05 12:36
2012.04.29
Вопрос о передаче фокуса элементу





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский