问题描述
有没有人试图利用资料perlembed在单Linux上
Has anyone attempted using perlembed in Mono on Linux?
下面是链接:的
下面是我在的DllImport签名第一次尝试:
Here is my first attempt at the DllImport signatures:
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);
的
核心目录可以为每个Linux发行版改变。
The CORE directory can change per Linux distro.
下面的代码运行,但在解析()
方法崩溃:
The following code runs, but crashes on the Parse()
method:
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());
}
我崩溃写道:
My crash reads:
=================================================================
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,intptr,int,System.Text.StringBuilder,System.Text.StringBuilder) <0xffff9f85>
in Woot:Main () <0x8d>
in (wrapper runtime-invoke) System.Object:runtime_invoke_void (object,intptr,intptr,intptr) <0x7c79b09>
本机堆栈跟踪:
Native stacktrace:
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]
有一些 PERL_SYS_INIT3
和 PERL_SYS_TERM
调用 perlembed 提到,但我一直无法通过的DllImport
。我总是 EntryPointNotFoundException
在这种情况下。我敢肯定,他们在不同的文件,我需要进口。
There are some PERL_SYS_INIT3
, and PERL_SYS_TERM
calls that perlembed mentions, but I have not been able to call those methods through DllImport
. I always get EntryPointNotFoundException
in those cases. I'm sure they are in a different file I need to import.
有人可以告诉我正确的方法来调用 DllImports
来perlembed?
Can someone direct me in the correct way to call DllImports
to perlembed?
推荐答案
得到它的工作!
提出的perl程序, showtime.pl
Made the perl program, 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;
}
}
通过它编译:
Compiled it via:
"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!...");
}
}
用的GMC编译它,得到的输出:
Compiled it with gmcs, and got the output:
Starting up C#...
WOOT!
DONE!...
希望这可以帮助那里的人,不能相信用了3种语言的情况发生。我将进入传入标量,数组等,但它应该是从这里轻而易举的事。
Hope this helps anyone out there, can't believe it took 3 languages to happen. I will move on to passing scalars, arrays, etc. but it should be a breeze from here.
这篇关于PerlEmbed - C# - 单 - 的Linux的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!