Pergunta

Eu tenho uma DLL Delphi com uma função definida como:

função SubmitJobStringList (Joblist: TStringList; var jobno: inteiro): Integer;

Eu estou chamando isso de C #. Como faço para declarar o primeiro parâmetro como um TStringList não existe no C #. Eu tenho atualmente a declaração como:

[DllImport("opt7bja.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int SubmitJobStringList(string[] tStringList, ref int jobno);

Mas quando eu chamá-lo eu recebo uma exceção de memória de violação de acesso.

conheço ninguém como passar para um TStringList corretamente a partir de C #?

Foi útil?

Solução

Você provavelmente não tem nenhuma sorte com isso. O TStringList é mais do que apenas uma matriz, é uma classe full-blown, e os exatos detalhes de implementação podem ser diferentes do que é possível com .NET. Dê uma olhada no código fonte Delphi VCL (isto é, se tiver) e tentar descobrir se você pode reconstruir a classe em C #, e passá-lo com a ajuda de seu melhor amigo, o Interop Marshaller. Note-se que mesmo o tipo string Delphi é diferente do tipo string NET, e passá-la sem dizer o marshaller o que deveria fazer, ele vai passá-lo como um char-array, mais provável.

Além disso, gostaria de sugerir mudar o Delphi DLL. Nunca é uma boa coisa para expor específica Delphi-qualquer coisa em uma DLL que está a ser utilizado por clientes não-Delphi. Faça o parâmetro um array de PChar e você deve ser fino.

Outras dicas

Se esta é sua DLL, eu reescrever a função para aceitar uma matriz de strings em vez. Evitar passar as classes como parâmetros DLL.

Ou, se você realmente quiser usar um TStringList por algum motivo, VCL.Net da Delphi pode ser usado de qualquer linguagem .NET.

Um exemplo de idade usando TIniFile: http://cc.codegear.com/Item/22691

O exemplo usa .Net 1.1 em Delphi 2005. Delphi 2006 e 2007 suporte .Net 2.0.

Se você não controlar a DLL e eles não podem ou não vai mudá-lo, você sempre pode escrever seu próprio invólucro Delphi em uma DLL separada com parâmetros que são mais cross-language amigável.

Ter uma classe como um parâmetro de uma função DLL é realmente má forma.

Eu não sou exatamente limpar sua maneira de usar Delphi e C #. Parece que você tenha criado uma DLL Win32 que você quiser chamar de C #. Offcourse você deve estar usando PInvoke para isso.

Gostaria de sugerir que você cria uma DLL .NET usando seu código fonte desde portabilidade completa de VCL está disponível. I pode ainda elaborar, se desejar ....

Em teoria, você poderia fazer algo assim usando ponteiros (fazendo-os como o tipo C # IntPtr) em vez de referências de objeto rigidez (ou talvez envolvê-los em algum outro tipo para evitar ter de declarar blocos inseguras), mas o problema essencial é esta: o tempo de execução Delphi deve ser o mecanismo para alocação e desalocação de memória para os objetos. Para esse fim, você deve declarar funções na sua DLL Delphi-compilado que invocam os construtores e destruidores para a classe TStringList, você deve se certificar de que o seu Delphi DLL usa a unidade ShareMem, e você deve assumir a responsabilidade de incrementar e decrementar a contagem de referência para o seu Delphi AnsiStrings antes de saírem da DLL e depois inseri-lo, de preferência, também como funções exportados de seu Delphi DLL.

Em suma, é um muito de trabalho desde que você deve conciliar dois gerenciadores de memória no mesmo processo (os alocadores .NET CLR e Delphi'S) e você deve tanto gerenciar a memória manualmente e "tolo" o gerenciador de memória Delphi e tempo de execução. Existe uma razão particular, você é obrigado a esta configuração? Você poderia descrever o problema que você está tentando resolver a um nível superior?

Como Hemant Jangid disse, você deve facilmente ser capaz de fazer isso por compilar seu código como um .NET DLL e, em seguida, referindo-se que a montagem em seu projeto c #.

Claro, você só vai ser capaz de fazer isso se a versão do Delphi você tem tem Delphi.NET.

Eu não sei muito sobre c #, mas uma técnica que eu uso para o transporte de stringlists entre contextos está usando a propriedade .text para obter uma string representando a lista, em seguida, atribuir essa propriedade no "outro lado".

Geralmente é mais fácil obter uma corda por cima do muro que é um objeto desenvolvido.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top