PerlEmbed - C# - моно - Linux

SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd" );
Calendar cal = Calendar.getInstance();
cal.setTime( dateFormat.parse( inputString ) );
cal.add( Calendar.DATE, 1 );
6
задан Sinan Ünür 29 July 2009 в 00:29
поделиться

2 ответа

Все заработало!

Создал программу 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 языка. Я перейду к передаче скаляров, массивов и т. Д., Но отсюда будет проще простого.

6
ответ дан 10 December 2019 в 02:51
поделиться

Не удается выполнить perl_parse (), потому что ваша привязка неверна.

Аргумент argv - это char ** (интерпретируется как массив char * размером с argc): это имеет не имеет отношения к StringBuilder, который представляет изменяемую строку.

Я предлагаю вам вручную маршалировать этот массив: используйте IntPtr [] в качестве аргументов argv и env и заполните элементы массива указателями на байтовые строки, например, используя Marshal .StringToCoTaskMemAnsi (), если кодировка вам подходит. Не забудьте также освободить память, выделенную этим.

Конечно, вы должны сделать всю эту работу внутри вспомогательного метода, который предоставляет программистам на C # более естественный интерфейс, который принимает строку [] вместо пары argc / argv.

3
ответ дан 10 December 2019 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: