PerlEmbed – C# – Mono – Linux
发布时间:2020-12-15 08:14:17 所属栏目:百科 来源:网络整理
导读:有没有人试图在 Linux上使用Mono for Monombed? 这是链接:perlembed 这是我第一次尝试DllImport签名: private const string PERL_LIB = "/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libperl.so";[DllImport(PERL_LIB,EntryPoint = "perl_alloc",
有没有人试图在
Linux上使用Mono for Monombed?
这是链接:perlembed 这是我第一次尝试DllImport签名: private const string PERL_LIB = "/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libperl.so"; [DllImport(PERL_LIB,EntryPoint = "perl_alloc",SetLastError = true)] public static extern IntPtr Alloc(); [DllImport(PERL_LIB,EntryPoint = "perl_construct",SetLastError = true)] public static extern void Construct(IntPtr hPerl); [DllImport(PERL_LIB,EntryPoint = "perl_destruct",SetLastError = true)] public static extern void Destruct(IntPtr hPerl); [DllImport(PERL_LIB,EntryPoint = "perl_free",SetLastError = true)] public static extern void Free(IntPtr hPerl); [DllImport(PERL_LIB,EntryPoint = "perl_parse",SetLastError = true)] public static extern void Parse(IntPtr hPerl,IntPtr @null,int argc,StringBuilder argv,StringBuilder env); [DllImport(PERL_LIB,EntryPoint = "perl_run",SetLastError = true)] public static extern void Run(IntPtr hPerl); [DllImport(PERL_LIB,EntryPoint = "eval_pv",SetLastError = true)] public static extern void Eval(string expr,bool flag); CORE目录可以根据Linux发行版进行更改. 运行以下代码,但在Parse()方法上崩溃: try { Console.WriteLine("Alloc"); IntPtr perl = Alloc(); Console.WriteLine("Construct"); Construct(perl); Console.WriteLine("Parse"); Parse(perl,IntPtr.Zero,3,new StringBuilder("-e 0"),new StringBuilder()); Console.WriteLine("Run"); Run(perl); Console.WriteLine("Eval"); Eval("$a = 3.14; $a **= 2",true); Console.WriteLine("Destruct"); Destruct(perl); Console.WriteLine("Free"); Free(perl); } catch (Exception exc) { Console.WriteLine(exc.ToString()); } 我的崩溃写道: ================================================================= Got a SIGSEGV 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: in (wrapper managed-to-native) Woot:Parse (intptr,intptr,int,System.Text.StringBuilder,System.Text.StringBuilder) <0x4> in (wrapper managed-to-native) Woot:Parse (intptr,System.Text.StringBuilder) <0xffff9f85> in Woot:Main () <0x8d> in (wrapper runtime-invoke) System.Object:runtime_invoke_void (object,intptr) <0x7c79b09> 本机堆栈跟踪: mono(mono_handle_native_sigsegv+0xbb) [0x81368fb] mono [0x8105670] [0x4c45a440] /usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libperl.so(perl_parse+0xa3) [0x4c6e6e93] [0x43ad78] [0x434cae] [0x434abe] mono(mono_runtime_exec_main+0x62) [0x80ae5a2] mono(mono_runtime_run_main+0x152) [0x80af6e2] mono(mono_main+0xef9) [0x805dae9] mono [0x805c702] /lib/libc.so.6(__libc_start_main+0xdc) [0x4c48d724] mono [0x805c651] perlembed提到了一些PERL_SYS_INIT3和PERL_SYS_TERM调用,但是我无法通过DllImport调用这些方法.在这些情况下我总是得到EntryPointNotFoundException.我确定它们在我需要导入的不同文件中. 有人可以用正确的方式指导我调用DllImports perlembed吗? 解决方法
搞定了!
制作了perl程序,showtime.pl: #/usr/bin/perl sub showtime { print "WOOT!n"; } 制作了c程序,perlembed.c: #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; void Initialize(char* processName,char* perlFile) { int argc = 2; char *argv[] = { processName,perlFile },*env[] = { "" }; PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl); perl_parse(my_perl,NULL,argc,argv,NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; } void Call(char* subName) { char *args[] = { NULL }; call_argv(subName,G_DISCARD | G_NOARGS,args); } void Dispose() { if (my_perl != NULL) { perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); my_perl = NULL; } } 通过以下方式编译: "gcc -shared -Wl,-soname,perlembed.so -o perlembed.so perlembed.c `perl -MExtUtils::Embed -e ccopts -e ldopts`" 制作了这个C#程序,perlembed.cs: using System; using System.Runtime.InteropServices; public class Woot { [DllImport("perlembed.so",SetLastError = true)] public static extern void Initialize(string processName,string perlFile); [DllImport("perlembed.so",SetLastError = true)] public static extern void Call(string subName); [DllImport("perlembed.so",SetLastError = true)] public static extern void Dispose(); static void Main() { Console.WriteLine("Starting up C#..."); try { Initialize("perlembed.exe","showtime.pl"); Call("showtime"); } catch(Exception exc) { Console.WriteLine(exc.ToString()); } finally { Dispose(); } Console.WriteLine("DONE!..."); } } 用gmcs编译它,得到输出: Starting up C#... WOOT! DONE!... 希望这可以帮助那里的任何人,不能相信它需要3种语言才能实现.我将继续传递标量,数组等,但这应该是一件轻而易举的事. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |