Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
delphi:dll没有用于字符串传输的内存管理器_Delphi_Dll_Delphi Xe - Fatal编程技术网

delphi:dll没有用于字符串传输的内存管理器

delphi:dll没有用于字符串传输的内存管理器,delphi,dll,delphi-xe,Delphi,Dll,Delphi Xe,德尔福Xe 它被给出: 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 Gu

德尔福Xe

它被给出:

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.
要下载源代码,可以在以下位置下载:

通过按下按钮,在dll行(ansi或宽字符串)中传输,在msgbox dll中显示,在那里处理(空闲时间大写)并返回到程序。未使用内存管理器(fast-simple-sharem)。程序和dll中都包含ReportMemoryLeaksOnShutdown(显示有关内存丢失的事件),这两个都是静默的,也就是说,与所有程序一样,各处的行长度也过于一致

这是必要的

  • 查看是否没有错误(检查错误)

  • 是否有可能优化或提供更好或更容易的方法

  • 是否可以使用VB或C++/C#中的此类过程来寻址此DLL

  • 谢谢你的代码

    SetLength(s, trunc(l/sizeof(widechar)));
    Move(p^, Pointer(s)^, l);
    
    您将最终导致程序堆损坏;我想你是说

    SetLength(s, l);
    Move(p^, Pointer(s)^, l * sizeof(widechar));
    


    由于Dll在接口部分不使用托管字符串类型,因此它不需要共享内存管理器,并且可以与其他语言(如VB或C++/C#)一起使用。

    您太复杂了。Delphi语言/库将处理字符串和指向以null结尾的字符数组的指针之间的转换

    unit DllUnit; 
    
    interface
    
    uses 
      windows, sysutils;
    
    Procedure GuPrcA(var p:PAnsiChar); StdCall;
    Procedure GuPrcW(var p:PWideChar); StdCall;
    
    Exports 
      GuPrcA,GuPrcW;
    
    implementation
    
    procedure GuMes(s:string);
    begin
      MessageBox(0,pchar(s),'From dll',mb_iconinformation);
    end;
    
    Procedure GuPrcW(var p:PWideChar); // wide
    var
      s: string;
    begin
      s := p;
      gumes(s);
    end;
    
    Procedure GuPrcA(var p:Pansichar); // ansi
    var
      s: string;
    begin
      s := p;
      gumes(s);
    end;
    
    Initialization
      ReportMemoryLeaksOnShutdown:=true;
    
    end.
    
    调用例程也是如此

    Procedure GuPrcA(var p:PansiChar); StdCall; external 'mydll.dll' name 'GuPrcA';
    Procedure GuPrcW(var p:PwideChar); StdCall; external 'mydll.dll' name 'GuPrcW';
    
    procedure TForm1.Button6Click(Sender: TObject);
    var
      s: UnicodeString;
    begin
      s := memo1.Text;
      GuPrcW(PWideChar(s));
    end;
    
    procedure TForm1.Button7Click(Sender: TObject);
    var
      s: AnsiString;
    begin
      s := memo1.Text;
      GuPrcA(PAnsiChar(s));
    end;
    
    我省略了您包含的所有诊断代码。如果要在显示文本之前或在将其传递到DLL之前对其进行修改,那么这很容易。在本地字符串变量中使用标准字符串操作进行修改(始终命名为
    s

    例如:

    Procedure GuPrcA(var p:Pansichar); // ansi
    var
      s: string;
    begin
      s := p;
      s := s + '-' + Length(s);
      gumes(s);
    end;
    


    底线是,您完全不需要编写在字符串和指针之间转换为以null结尾的字符数组的代码,因为Delphi将为您做这件事。

    如果您不想使用堆管理器传输数据,只需使用
    WideString
    类型的字符串即可

    它会(稍微)慢一点,但它允许您更改每边的字符串长度

    它将是真正的Unicode,所以在XE下使用本机Delphi
    UnicodeString
    时,您不会遇到任何字符集之类的问题。您可以在代码中使用
    WideString
    ,到
    string
    的转换将以静默方式完成


    它将全部由Windows管理,因此即使是非Delphi库或应用程序(如.Net或C++)也可以直接处理它。

    setlength…=在dll和程序中?@serg奇怪的是,q中的代码传递的是字节大小而不是字符串length@david在任何情况下,OP代码对于奇数
    l
    值都是不正确的。您最好使用一行:
    SetString(s,p,l)
    ,它可以毫无问题地替换两个SetLength+Move。如果需要接收字符串,在dll中的输入处。如果有必要从Dll传输,请执行该移动。没什么大区别吗?没有。这里显示的一条线让我有点兴奋。问题:要在DLL中传输字符串,要在那里显示它(仅查看是否正确传输),\u要处理(转换/修改/ect)并返回到程序中。特别是宽字符串,在数组的中间可以是其他编码或2字节符号0,你是什么意思?没有什么?在所有情况下,我都认为使用字符串作为缓冲区比手动内存分配更容易。如果是,为什么?字符串列表?通常使用双空终止完成。+1是的,
    WideString
    ,也称为
    BSTR
    ,是互操作的一个很好的选择。您是如何使用这种编码风格的-/@不,你不能。你有一个很大的问题,就是你没有缩进你的代码。更大的问题是没有换行符和无用的前缀符号。
    Procedure GuPrcA(var p:Pansichar); // ansi
    var
      s: string;
    begin
      s := p;
      s := s + '-' + Length(s);
      gumes(s);
    end;
    
    procedure TForm1.Button7Click(Sender: TObject);
    var
      s: AnsiString;
    begin
      s := memo1.Text;
      s := s + '-' + Length(s);
      GuPrcA(PAnsiChar(s));
    end;