I'm stucked with a problem with Mono Interop in Linux. I have a native shared library (made in Lazarus) that I need to use in a C# assembly. The shared library is used by a Mono C# assemblie on Windows and on Linux.
The assembly loads the shared library via DllImport at runtime, and calls an exported function that generates a file and returns a string with the new file's name. The function in the shared library works fine, but in Linux the Mono runtime crashes at Object.__icall_wrapper_mono_marshal_free when the function returns. This works fine using Mono on Windows.
I've made several tests and I can tell that the shared library actually works (the new file is generated at the specified path), but in the end the runtime crashes. It seems that the runtime has problems with the marshaling of the resulting string back to the assembly, because it works if I use an exported function that returns an int.
My shared library is something like this:
library fileProcessing;
{$mode objfpc}{$H+}
...
function ProcessFile(File, ResultPath: PChar): PChar; cdecl; // returns a null-terminated string, with a C ABI calling convention
var
sFile, sPath, sResult: string;
begin
sFile := StrPas(File);
sPath := StrPas(ResultPath);
...
sResult := GenerateNewFile(sFile, sPath); // helper function that generates the file and returns its filename
Result := stralloc(length(sResult) + 1);
Result := strpcopy(Result, sResult);
end;
...
exports ProcessFile name 'ProcessFile';
The calling C# assembly goes like this:
namespace SIG
{
public class TsigKernel
{
...
[DllImport("fileProcessing.so", CharSet=CharSet.Ansi,
EntryPoint="ProcessFile",
CallingConvention=CallingConvention.Cdecl, SetLastError = true)]
private static extern string ex_ProcessFile(string File, string ResultPath);
// managed wrapper for the shared library exported function
public string ProcessFile(string File, string ResultPath)
{
return ex_ProcessFile(File, ResultPath);
}
...
}
}
I've tried several alternatives (returning a native string from the exported function, changing the calling convention to stdcall on the assembly and the shared library, changing the charset in the DllImport).
I'm sure that I'm missing something, but I haven't found anything about this problem on Google.
My crash reads:
=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================
Stacktrace:
at (wrapper managed-to-native) object.__icall_wrapper_mono_marshal_free (intptr) <0x00004>
at (wrapper managed-to-native) object.__icall_wrapper_mono_marshal_free (intptr) <0x00004>
at (wrapper managed-to-native) SIG.TsigKernel.ex_ProcessFile (string, string) <0x00064>
at SIG.TsigKernel.ProcessFile (string, string) <0x00010>
at TEST.Form1.Form1_Load (object,System.EventArgs) <0x00047>
at System.Windows.Forms.Form.OnLoad (System.EventArgs) <0x00060>
at System.Windows.Forms.Form.OnLoadInternal (System.EventArgs) <0x00081>
at System.Windows.Forms.Form.OnCreateControl () <0x00051>
at System.Windows.Forms.Control.CreateControl () <0x0012e>
at System.Windows.Forms.Control.WmShowWindow (System.Windows.Forms.Message&) <0x0010f>
at System.Windows.Forms.Control.WndProc (System.Windows.Forms.Message&) <0x00292>
at System.Windows.Forms.ScrollableControl.WndProc (System.Windows.Forms.Message&) <0x00013>
at System.Windows.Forms.ContainerControl.WndProc (System.Windows.Forms.Message&) <0x00051>
at System.Windows.Forms.Form.WndProc (System.Windows.Forms.Message&) <0x0022a>
at System.Windows.Forms.Control/ControlWindowTarget.OnMessage (System.Windows.Forms.Message&) <0x0001d>
at System.Windows.Forms.Control/ControlNativeWindow.WndProc (System.Windows.Forms.Message&) <0x0002d>
at System.Windows.Forms.NativeWindow.WndProc (intptr,System.Windows.Forms.Msg,intptr,intptr) <0x001eb>
at System.Windows.Forms.XplatUIX11.SendMessage (intptr,System.Windows.Forms.Msg,intptr,intptr) <0x002ae>
at System.Windows.Forms.XplatUIX11.MapWindow (System.Windows.Forms.Hwnd,System.Windows.Forms.WindowType) <0x0019a>
at System.Windows.Forms.XplatUIX11.CreateWindow (System.Windows.Forms.CreateParams) <0x00bb4>
at System.Windows.Forms.XplatUI.CreateWindow (System.Windows.Forms.CreateParams) <0x0001d>
at System.Windows.Forms.NativeWindow.CreateHandle (System.Windows.Forms.CreateParams) <0x00030>
at System.Windows.Forms.Control.CreateHandle () <0x0007f>
at System.Windows.Forms.Form.CreateHandle () <0x00014>
at System.Windows.Forms.Control.CreateControl () <0x0008a>
at System.Windows.Forms.Control.SetVisibleCore (bool) <0x00079>
at System.Windows.Forms.Form.SetVisibleCore (bool) <0x0021d>
at System.Windows.Forms.Control.set_Visible (bool) <0x0002c>
at (wrapper remoting-invoke-with-check) System.Windows.Forms.Control.set_Visible (bool) <0x00057>
at System.Windows.Forms.Application.RunLoop (bool,System.Windows.Forms.ApplicationContext) <0x001f9>
at System.Windows.Forms.Application.Run (System.Windows.Forms.ApplicationContext) <0x00052>
at System.Windows.Forms.Application.Run (System.Windows.Forms.Form) <0x00033>
at TEST.Program.Main () <0x00044>
at (wrapper runtime-invoke) object.runtime_invoke_void (object,intptr,intptr,intptr) <0x0003a>
Native stacktrace:
mono [0x80d36a9]
[0xffffe410]
[0xffffe430]
/lib/libc.so.6(gsignal+0x4f) [0xb76430cf]
/lib/libc.so.6(abort+0x187) [0xb76449e7]
/lib/libc.so.6 [0xb767f4ed]
/lib/libc.so.6 [0xb768550b]
/lib/libc.so.6 [0xb7686de4]
/lib/libc.so.6(cfree+0x6d) [0xb7689fdd]
/usr/lib/libglib-2.0.so.0(g_free+0x36) [0xb780d886]
[0xb6561634]
[0xb5786a5d]
[0xb57869d1]
[0xb57866c8]
[0xb5786599]
[0xb578632a]
[0xb5785f7a]
[0xb605dbe7]
[0xb578c7c0]
[0xb578bbfb]
[0xb57820c4]
[0xb578208a]
[0xb5781eeb]
[0xb578b95e]
[0xb578b936]
[0xb578ac74]
[0xb5788acf]
[0xb578c4b3]
[0xb605eca5]
[0xb605e0e6]
[0xb605e069]
[0xb605ddf0]
[0xb57804bd]
[0xb605db43]
[0xb57938a2]
[0xb57800a6]
[0xb57937f5]
[0xb5793798]
[0xb577f062]
[0xb577ee13]
[0xb577eacc]
[0xb71ce1f5]
[0xb71ce26b]
mono [0x8063552]
Any ideas?