AccessViolationException podczas wywołania funkcji z biblioteki Delphi w aplikacji C#

0

Otóż problem ma się następująco - mam pewien program w Delphi korzystający z gotowego algorytmu który znajduje się w jednym z modułów. Algorytm ten muszę wykorzystać w aplikacji C#, stąd też pomysł żeby sam moduł odpowiednio przerobić i skompilować jako dll. Tak też zrobiłem, biblioteka zaimportowana w projekcie z następującymi opcjami:

Build action = None
Copy to Output Directory = Copy always

Sprawdziłem czy jestem w stanie wywołać jakąś podstawową funkcję:

[DllImport("ualglin.dll",
            CallingConvention = CallingConvention.StdCall,
            CharSet = CharSet.Ansi)]
public static extern void InvMatK(float[,] a, byte n, float eps);

Zwraca poprawny wynik. Szczęście trwało do momentu napotkania poniższej deklaracji w bibliotece:

procedure matrix(var prog:byte;var h2:integer; m,n,s1,s2,s4,s5:byte;d,w:strahl2;axy:daten;eps:dielektr;var c:macd); stdcall;

Gdzie:

const matrixmax  =  820;
      leitermax  =  10;

type vector     =   array [0..matrixmax] of real;
     macd       =   array [1..matrixmax] of ^vector;
     strahl2    =   array [0..2*leitermax, 0..2*leitermax] of real;
     dielektr   =   array [0..leitermax] of real;
     daten      =   array [0..leitermax, 0..1] of real;

Tak więc na moje funkcja przyjmuje jako zwracany parametr tablicę wskaźników na tablice liczb zmiennoprzecinkowych(?).
Spróbowałem funkcję zadeklarować następująco:

 [DllImport("ualglin.dll",
                CallingConvention = CallingConvention.StdCall,
                CharSet = CharSet.Ansi)]
  public static unsafe extern void matrix(byte prog, int h2, byte m, byte n, byte s1, byte s2, byte s4, byte s5, float[,] d, float[,] w, float[,] axy, float[] eps, float*[] c);

Raczej nie wierząc w powodzenie tej operacji. Wynikiem tego jest błąd:

System.AccessViolationException was unhandled
HResult=-2147467261
Message=Nastąpiła próba odczytu lub zapisu pamięci chronionej. Często wskazuje to, że inna pamięć jest uszkodzona.
Source=Przewody
StackTrace:
w Przewody.CCalc.matrix(Byte prog, Int32 h2, Byte m, Byte n, Byte s1, Byte s2, Byte s4, Byte s5, Single[,] d, Single[,] w, Single[,] axy, Single[] eps, Single*[] c)
w Przewody.CCalc.Calculate(List`1 wires) w c:\Users\Mateusz\Documents\Visual Studio 2012\Projects\Przewody\Przewody\CCalc.cs:wiersz 72
w Przewody.Form1.calcButton_Click(Object sender, EventArgs e) w c:\Users\Mateusz\Documents\Visual Studio 2012\Projects\Przewody\Przewody\Form1.cs:wiersz 571
w System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
w System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)
w System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
w System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
w System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
w System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
w System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
w System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
w System.Windows.Forms.Control.WndProc(Message& m)
w System.Windows.Forms.ScrollableControl.WndProc(Message& m)
w System.Windows.Forms.ToolStrip.WndProc(Message& m)
w System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
w System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
w System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
w System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
w System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
w System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
w System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
w System.Windows.Forms.Application.Run(Form mainForm)
w Przewody.Program.Main() w c:\Users\Mateusz\Documents\Visual Studio 2012\Projects\Przewody\Przewody\Program.cs:wiersz 19
w System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
w System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
w Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
w System.Threading.ThreadHelper.ThreadStart_Context(Object state)
w System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
w System.Threading.ThreadHelper.ThreadStart()
InnerException:

Na początku otrzymywałem taki błąd przy próbie skorzystania z jakiejkolwiek funkcji z biblioteki, ale pomogło dodanie do jej głownej funkcji:

begin
  IsMultiThread := True;
end.

Próbowałem dodania

uses ShareMem 

Jako pierwsze na liście ale bez efektu.

Czy ktoś ma jakiś pomysł jak ten problem rozwiązać, co podać jako parametr po stronie wywołania w C#?
Wiem, że najlepszą opcją byłoby przepisanie całego algorytmu, ale czas mocno nagli, a i sam algorytm to mnóstwo operacji na macierzach których nie rozumiem i szczerze mówiąc nie chciałbym się w nie zbyt zagłębiać.

0
  1. W deklaracji funkcji po stronie Delphi nie masz zdefiniowanej calling convention (StdCall)
  2. Jaka wersja delphi? Może to być o tyle istotne, że w zależności od wersji Real może mieć różny rozmiar.
0
  1. Ominąłem przy kopiowaniu, już wkleiłem poprawną wersję kodu w pierwszym poście. Dzięki za zwrócenie uwagi.
  2. Bibliotekę skompilowałem w Delphi XE8

1 użytkowników online, w tym zalogowanych: 0, gości: 1