Я пытаюсь использовать PInvoke для вызова неуправляемой функции из C dll. В связи с тем, что источник dll не может быть выпущен разработчикам, некоторые из них вызвали функцию в Delphi, используя следующую декларацию. Мы используем SAT.dll с конвенцией о вызове CDECL.AccessViolationException при вызове функции C из dll на C#
function AssociarAssinatura(numeroSessao : Longint; codigoDeAtivacao: PChar;
CNPJvalue : PChar; assinaturaCNPJs : PChar) : PChar ;
cdecl; External 'SAT.DLL';
На основе этой структуры, я сделал следующее консольное приложение в C#, чтобы проверить ту же самую функцию из одной и той же DLL. Я сделал некоторые исследования и выяснил, что эквивалент Longint в delphi является int в C#, и эквивалент 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 пытается освободить возвращенную строку. Вам нужно объявить возвращаемый тип как IntPtr и маршалировать его самостоятельно с помощью Marshal.PtrToStringAnsi(). Но у вас все еще нет хорошего способа освободить строку, которая станет утечкой памяти, которая в конечном итоге приведет к сбою вашей программы с помощью OOM. –
Есть ли что-нибудь, что я могу сделать? – Levrak
Это сработало! Благодаря! @HansPassant – Levrak