Francesco Perrotti wrote: > Oi pessoal, > > Tenho algumas dúvidas sobre o uso de PChar, agradeceria alguma ajuda. > > É o seguinte, fiz uma DLL com uma função que precisa retornar uma string, > portanto tenho que usar um PChar > já que provalvelmente a DLL será usada com linguagem C.
Se você envia strings para a dll, você pode criar um tipo string e fazer um cast para pchar. Uma ansi string é compatível com pchar internamente. > Só que ainda não consegui entender direito como o Delphi trata esse tipo. Por > exemplo, > se eu declarar em uma função: > > var p:pchar; > > o que exatamente o delphi cria? apenas um ponteiro para chars? ele já aloca > memória > para conter strings? se eu tiver que retornar um pchar por uma função, por > exemplo: Nada de alocação, apenas um tipo ponteiro. > function Hello: pchar; > begin > result := 'Hello'; > end; 'Hello' é uma literal que é alocada e liberada pelo compilador, e neste caso específico você não terá problemas nem com memória corrompida nem com vazamento. > isso está correto? ou tenho que alocar memória para o pchar como eu teria que > fazer em c? É como programar em C, exatamente. No caso acima você não precisa alocar porque a string é uma literal, mas nos demais casos você tem que cuidar se as rotinas que você está manipulando estão alocando memória corretamente. E se estão alocando, tenha em mente aonde e como elas serão desalocadas. > nesse caso o delphi já coloca o terminador zero no final ou eu devo colocar > explicitamente? Ansi strings são compatíveis com pchar, elas já possuem um #0 no final. Até isso o Delphi e o fpc faz por nós. > E no lugar onde faço a chamada a essa função, depois eu tenho que liberar a > memória? > Por exemplo: > > var p: pchar; > begin > p := Hello; > > e agora? depois de usar a string em p o que eu devo fazer? liberar a memória? > ou o delphi já faz isso? > No help do delphi há exemplos usando arrays de char que depois são > "casteados" para pchar, Usando um array de char (com um #0 no final) ou string, o compilador irá alocar e desalocar a memória por você, mas cuidado para não mandar uma string para outra rotina sendo que a string foi alocada localmente (tal como uma variável local). Depois que a sua rotina terminar, babau string. Exemplo, isto aqui funciona: var VStr: string; begin VStr := Copy(Alguem, AlgumaPos, AlgumTamanho); ChamaDll(PChar(VStr)); end; A string é alocada por Copy, guardada em VStr, é passado para ChamaDll como um PChar, e depois que volta da rotina ChamaDll é que é desalocada pelo compilador. > mas no meu caso eu não sei qual será o tamanho final da string, devo alocar > um array dentro da função > e liberar ele fora dela? Ou isso, ou usar ansi strings, ou usar StrAlloc, ou usar GetMem, ou usar alguma rotina que se preocupe com isto (exemplo strpcopy), etc. E lembrar de desalocar essa memória caso tenha sido alocada por você ou por alguma rotina que você chamou. Geralmente, ao programar com bibliotecas de link dinâmico, é comum utilizar ansi strings na aplicação e fazer um cast forçado na chamada à rotina. Todo o trabalho de alocação fica transparente pra você e você tem mais tempo para se preocupar com coisas mais importantes. Joao Morais