Array
(
)

DLLImport

Ecq
   - 13 ago 2007

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.

Ecq
   - 15 ago 2007

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

Ecq
   - 04 set 2007

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

Massuda
   - 04 set 2007

Assumindo que essa sua DLL seja código não-gerenciado, acho que o erro está aqui...
Citação:
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...#Código

[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.