Я пытаюсь использовать старую C DLL в приложении Windows Forms. Кажется, я использую неправильный тип данных для выходного параметра.Использование DLL в C#
DLL, исходный код:
#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif
EXPORT INT CALLBACK Complemento (LPSTR) ;
EXPORT INT CALLBACK MatchCode (LPSTR, LPSTR, LPSTR, LPSTR);
C# DLL Экспорт
[DllImport(
@"<MYDIR>Fonetica.dll",
CharSet = CharSet.Ansi)]
public static extern int MatchCode(
String n,
String s,
String e,
[MarshalAs(UnmanagedType.LPStr)] out String retorno);
C# DLL код использования
String match = String.Empty;
MatchCode(pefi.Nome, String.Empty, String.Empty, out match);
дереве первые параметры являются входными и последний является выходом.
I'm получать это исключение:
System.AccessViolationException was unhandled
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=mscorlib
StackTrace:
at System.String..ctor(SByte* value)
at System.StubHelpers.CSTRMarshaler.ConvertToManaged(IntPtr cstr)
at WFMatchCode.Form1.MatchCode(String n, String s, String e, String& retorno)
at WFMatchCode.Form1.button1_Click(Object sender, EventArgs e) in C:\Users\computecnica.alexand\Documents\Visual Studio 2010\Projects\WFMatchCode\WFMatchCode\Form1.cs:line 91
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at WFMatchCode.Program.Main() in c:\users\computecnica.alexand\documents\visual studio 2010\Projects\WFMatchCode\WFMatchCode\Program.cs:line 18
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Ваш C dll кажется странным. Как люди могут знать, что вводится и что выводится? Первые три параметра должны быть как минимум LPCSTR. И в выходном параметре отсутствует параметр, как долго может быть записан массив. Что бы вы ожидали, что маршаллинг переходит к этой функции в качестве параметра вывода? Насколько велик массив символов? – nvoigt
@alexandre Передача 'out string' выполняется с помощью' StringBuilder'. Найдите вокруг pinvoke 'StringBuilder', и вы найдете много примеров. – xanatos
@nvoigt Большое спасибо, но этому исходному коду 13 лет, и я не хочу его менять ... Спасибо в любом случае. –