本文介绍了PerlEmbed - C# - 单 - 的Linux的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人试图利用资料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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-17 11:41