1

問題...

MacPerlは64ビットperlでサポートされなくなったため、Terminal.appを制御するための代替フレームワークを試しています。

ScriptingBridgeを試していますが、 PerlObjCBridgeを使用して列挙型文字列をcloseSavingメソッドに渡す際に問題が発生しました。

電話したい:

typedef enum {
    TerminalSaveOptionsYes = 'yes ' /* Save the file. */,
    TerminalSaveOptionsNo = 'no  '  /* Do not save the file. */,
    TerminalSaveOptionsAsk = 'ask ' /* Ask the user whether or not to save the file. */
} TerminalSaveOptions;

- (void) closeSaving:(TerminalSaveOptions)saving savingIn:(NSURL *)savingIn;  // Close a document.

試みられた解決策...

私が試してみました:

#!/usr/bin/perl

use strict;
use warnings;
use Foundation;

# Load the ScriptingBridge framework
NSBundle->bundleWithPath_('/System/Library/Frameworks/ScriptingBridge.framework')->load;
@SBApplication::ISA = qw(PerlObjCBridge);

# Set up scripting bridge for Terminal.app
my $terminal = SBApplication->applicationWithBundleIdentifier_("com.apple.terminal");

# Open a new window, get back the tab
my $tab = $terminal->doScript_in_('exec sleep 60', undef);
warn "Opened tty: ".$tab->tty->UTF8String; # Yes, it is a tab

# Now try to close it

# Simple idea
eval { $tab->closeSaving_savingIn_('no  ', undef) }; warn $@ if $@;

# Try passing a string ref
my $no = 'no  ';
eval { $tab->closeSaving_savingIn_(\$no, undef) }; warn $@ if $@;

# Ok - get a pointer to the string
my $pointer = pack("P4", $no);
eval { $tab->closeSaving_savingIn_($pointer, undef) }; warn $@ if $@;
eval { $tab->closeSaving_savingIn_(\$pointer, undef) }; warn $@ if $@;

# Try a pointer decodes as an int, like PerlObjCBridge uses
my $int_pointer = unpack("L!", $pointer);
eval { $tab->closeSaving_savingIn_($int_pointer,  undef) }; warn $@ if $@;
eval { $tab->closeSaving_savingIn_(\$int_pointer, undef) }; warn $@ if $@;

# Aaarrgghhhh....

ご覧のとおり、列挙型文字列を渡す方法についての私の推測はすべて失敗します。

あなたが私を炎上させる前に...

  • これを行うために別の言語(ruby、python、cocoa)を使用できることは知っていますが、それでは残りのコードを翻訳する必要があります。
  • CamelBonesを使用できるかもしれませんが、ユーザーがCamelBonesをインストールしているとは思いません。
  • NSAppleScriptフレームワークを使用することもできますが(タブIDとウィンドウIDを見つけるのに苦労したと仮定して)、この1回の呼び出しだけでNSAppleScriptフレームワークに頼らなければならないのは奇妙に思えます。
4

1 に答える 1

2
typedef enum {
    TerminalSaveOptionsYes = 'yes ' /* Save the file. */,
    TerminalSaveOptionsNo = 'no  '  /* Do not save the file. */,
    TerminalSaveOptionsAsk = 'ask ' /* Ask the user whether or not to save the file. */
} TerminalSaveOptions;

enum文字列定数には名前を付けません。int定数に名前を付けます。これらの名前はそれぞれint価値があります。

したがって、aまたはI代わりにパッキングしてみてください。または、次の両方を実行します。としてパックしてaから、として解凍しIてその番号を渡します。

于 2010-04-12T14:36:28.053 に答える