2012-06-24 3 views
4

// Дельфи код (Дельфи версии: Turbo Delphi Explorer (это Delphi 2006))Как назвать эту функцию delphi .dll с C#?

function GetLoginResult:PChar; 
    begin 
    result:=PChar(LoginResult); 
    end; 

// C# код для использования выше функции Дельфах (я использую Unity3D, в C#)

[DllImport ("ServerTool")] 
private static extern string GetLoginResult(); // this does not work (make crash unity editor) 

[DllImport ("ServerTool")] 
[MarshalAs(UnmanagedType.LPStr)] private static extern string GetLoginResult(); // this also occur errors 

Каков правильный способ использования этой функции в C#?

(для использования в также в Дельфах, код подобен, , если (событие = 1) и (тэг = 10), то WriteLn ('Вход результат:', GetLoginResult);)

+0

Может помочь: http://stackoverflow.com/questions/5086645/how-to-use-delphi-dllwith-pchar-type-in-c-sharp –

ответ

8

Память для строка принадлежит вашему коде Delphi, но ваш код p/invoke приведет к тому, что маршаллер вызовет CoTaskMemFree на эту память.

Что вам нужно сделать, так это сообщить маршаллеру, что он не должен брать на себя ответственность за освобождение памяти.

[DllImport ("ServerTool")] 
private static extern IntPtr GetLoginResult(); 

Затем с помощью Marshal.PtrToStringAnsi() преобразовать возвращаемое значение в C# строка.

IntPtr str = GetLoginResult(); 
string loginResult = Marshal.PtrToStringAnsi(str); 

Вы также должны убедиться, что матч соглашения по вызову, объявив функцию Delphi быть stdcall:

function GetLoginResult: PChar; stdcall; 

Хотя бывает так, что это соглашение о вызове неправильно матч не имеет значения для функция, не имеющая параметров, и возвращаемое значение размера указателя.

Для того, чтобы все это работало, строковая переменная Delphi LoginResult должна быть глобальной переменной, чтобы ее содержимое было действительным после того, как возвращается GetLoginResult.

+0

Будет ли и в этом случае иметь дело с вызывающим соглашением? – Petesh

+0

@Petesh фактически нет, потому что функция не имеет параметров, а возвращаемое значение обрабатывается одинаково для stdcall и register. Но было бы лучше объявить функцию Delphi как stdcall. Спасибо за это. –

+0

Я уверен, что если вы определяете возвращаемое значение вашей функции DllImport как строки, маршаллер обрабатывает ее правильно, как описано в msdn (http://msdn.microsoft.com/en-us/library/e765dyyy.aspx). –

Смежные вопросы