C DLL에서 관리되지 않는 함수를 호출하기 위해 PInvoke를 사용하려고합니다. DLL 소스가 개발자에게 공개 될 수 없기 때문에 그 중 일부는 Delphi에서 다음 선언을 사용하여 함수를 호출했습니다. SAT.dll은 CDECL 호출 규칙과 함께 사용됩니다. 그 구조를 기반 C#에서 DLL에서 C 함수를 호출 할 때 AccessViolationException이 발생했습니다.
function AssociarAssinatura(numeroSessao : Longint; codigoDeAtivacao: PChar;
CNPJvalue : PChar; assinaturaCNPJs : PChar) : PChar ;
cdecl; External 'SAT.DLL';
는 I 동일한 DLL에서 동일한 기능을 테스트하기 위해 C 번호의 다음 콘솔 응용했다. 나는 약간의 연구를했고 델파이의 Longint에 상응하는 것은 C#에서 int이고 PChar와 같은 것은 문자열에 대한 포인터라는 것을 알았다. (그러나 나는 C#의 문자열을 사용했다.)
class Program
{
[DllImport("SAT.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern string AssociarAssinatura(int numeroSessao,
string codigoDeAtivacao, string CNPJvalue, string assinaturaCNPJs);
static void Main(string[] args)
{
Console.WriteLine("Comienza");
int numeroSessao = 111111;
string codigoDeAtivacao = "123123123";
string cnpJvalue = "2222222222222211111111111111";
string assinaturaCnpJs = "lrafwegmqcgvpzpbdmcmcgdvf";
string resposta = AssociarAssinatura(numeroSessao, codigoDeAtivacao,
cnpJvalue, assinaturaCnpJs);
Console.WriteLine(resposta);
}
}
내가 함수를 호출하면 AccesViolationException이 발생합니다. AssociarAssinatura의 코드에는 함수의 코드가 실제로 잘 돌아가고 있음을 보여주는 내부 인쇄물이 있습니다. 이 문제로 인해 함수가 값을 반환 할 때 문제가 발생했다고 생각합니다. 내 생각 엔 어떻게 든 호출 규칙에 문제가 있습니다. 이견있는 사람?
pinvoke marshaller가 반환 된 문자열을 해제하려고하면 충돌이 발생합니다. 반환 형식을 IntPtr로 선언하고 Marshal.PtrToStringAnsi()를 사용하여 반환 형식을 마샬링해야합니다. 하지만 여전히 문자열을 해제 할 수있는 좋은 방법이 없습니다. 그러면 메모리 누수가 발생하여 궁극적으로 OOM으로 프로그램이 중단됩니다. –
내가 할 수있는 일이 있습니까? – Levrak
효과가있었습니다! 감사! @HansPassant – Levrak