DLLImport

13/08/2007

0

Olha só, estou fazendo um webservice para uma empresa mas estou com um problema.

Podes me ajudar?



É o seguinte, criei um WS para acessar uma DLL para fornecer as funções da DLL na web.

Esta DLL faz tratamento de dados, por exemplo: padroniza nomes, endereços, ceps, cargos, etc.

Ela lê um banco local para fazer o tratamento dos dados.



Mas estou com problema no seguinte, por ex, na função ScrubberCargo. Esta recebe dois parâmetros, um string que é o nome do cargo e outro o tamanho padrão.

Se eu passar “Gerente de Produção“ a função deveria retornar “Ger. Produção” mas ela retorna a mesma coisa passada. Na verdade não é o retorno é um parâmetro passado como referencia (em c# ref).



Tens alguma experiência com isto?



Já fiz varias coisas e não dá certo. Já utilizei Ansi e Unicode na DLLImport do .Net. Já utilizei código unSafe (char * nmCargo) também. Não sei mais o que fazer.





Grato



Eder.


Responder

Posts

15/08/2007

Ecq

Das tentativas que fiz, algumas são:



1 – Utilizar passagem de parâmetro por referencia, por exemplo:

//comando para importar a função da DLL

[DllImport(´scrubber.dll´)]

private static extern int ScrubberCargo(ref string sCargo, int nTamanho);



//Declaração do método para disponibilizarão na WEB.

[WebMethod(Description=´padronização de cargo´)]

//Com Retorno de uma lista para exibir um XML no Browser

public ArrayList wScrubberCargo(string sCargo, int nTamanho)

{

//Cria a lista

ArrayList lista = new ArrayList();

//Declara uma variavel do tipo string que recebe o cargo passado

System.String sRetCargo = sCargo;

try

{

//Chama a função da DLL

int n = ScrubberCargo(ref sRetCargo, nTamanho);

//Adiciona o retorno da função a lista;

lista.Add(n.ToString());

//Adiciona o cargo alterado a lista

lista.Add(sRetCargo);

//Retorna a lista.

return lista;

}

catch (Exception ex)

{

//Em caso de erro retorna a a descrição do erro.

lista.Add(ex.ToString());

return lista;

}

}



2 – Também tentei utilizar código sem gerenciamento pelo “GC” que é o coletor de lixo (de memória) do .Net. Normalmente utilizado para acesso a DLL do win32. Por exemplo:



[DllImport(´scrubber.dll´)]

unsafe private static extern int ScrubberCargo(char * sCargo, int * nTamanho);



//E a chamada seria assim, neste caso.

unsafe {

// Ajusta o tamanho máximo

int * Comp = stackalloc int[nTamanho];

// Aloca buffer

char * Nome = stackalloc char[nTamanho];

// Chama função

n = ScrubberCargo(Nome, Comp);

//bool n1 = GetUserNameW(Nome, &Comp); //aqui um exemplo que funciona perfeitamente com a dll Advapi32.dll

// Converte para string e volta o valor

s = new string(Nome, 0, nTamanho);

}



3 – Tentei de varias formar trabalhar com os tipos de string ANSI e UNICODE, por exemplo:



[DllImport(´scrubber.dll´, CharSet = CharSet.Auto, ExactSpelling=true)]

ou

[DllImport(´scrubber.dll´, SetLastError=true, CharSet=System.Runtime.InteropServices.CharSet.Auto)]

ou

[DllImport(´scrubber.dll´, CharSet = CharSet.ANSI)]

ou

[DllImport(´scrubber.dll´, CharSet = CharSet.UNICODE)]



4 – E por ultimo, mas não finalmente, tentei utilizar outra forma de trabalhar sem gerenciamento de memória, exemplo:



private static extern int ScrubberCargo([MarshalAs(UnmanagedType.LPStr)] string sCargo, int nTamanho);



E infelizmente até agora não obtive sucesso nos testes.





Grato


Responder

04/09/2007

Ecq

Ainda estou com o problema citado acima.

Agora descobri, que se passar um parametro como REF a função da DLL não recebe o valor corretamente, recebe somente caractares estranhos.
Se passar sem o REF a ddl não altera o valor da variavel.

A dll somente recebe o valor corretamente com ref se for do tipo char.
Mas assim aceita somente um char, claro.

Minha duvida agora é tenho como passar uma variavel do tipo char com mais de um caracter?

Alguem pode me ajudar, esteu desesperado.

Grato

Eder.
edercq@gmail.com


Responder

04/09/2007

Massuda

Assumindo que essa sua DLL seja código não-gerenciado, acho que o erro está aqui...
2 – Também tentei utilizar código sem gerenciamento pelo “GC” que é o coletor de lixo (de memória) do .Net. Normalmente utilizado para acesso a DLL do win32. Por exemplo: [DllImport(´scrubber.dll´)] unsafe private static extern int ScrubberCargo(char * sCargo, int * nTamanho); //E a chamada seria assim, neste caso. unsafe { // Ajusta o tamanho máximo int * Comp = stackalloc int[nTamanho]; // Aloca buffer char * Nome = stackalloc char[nTamanho]; // Chama função n = ScrubberCargo(Nome, Comp); //bool n1 = GetUserNameW(Nome, &Comp); //aqui um exemplo que funciona perfeitamente com a dll Advapi32.dll // Converte para string e volta o valor s = new string(Nome, 0, nTamanho); }
...a chamada deveria ser...
[DllImport("scrubber.dll")]

unsafe private static extern int ScrubberCargo(char * sCargo, int * nTamanho);

//E a chamada seria assim, neste caso.

unsafe {
  
  // Ajusta o tamanho máximo
  int tamanho = nTamanho;

  // Aloca buffer
  char *nome = stackalloc char[nTamanho];

  // Chama função
  n = ScrubberCargo(nome, &tamanho);

  // Converte para string e volta o valor
  s = new string(nome, 0, tamanho);

  ...
}
...mas posso estar errado, já que não entendi completamente seus posts.


Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar