Смешивание C # с Objective-C

ВЕРСИЯ метод UNIVERSAL всех классов Perl. Можно использовать его для получения версии модуля (если это было установлено, который это обычно имеет).

Вот один лайнер, где только необходимо добавить имя модуля однажды:

perl -le 'eval "require $ARGV[0]" and print $ARGV[0]->VERSION' Some::Module

29
задан Moshe 18 April 2011 в 03:39
поделиться

2 ответа

Очевидно, что в Mac OS нет такого языка, как C ++ / CLI. В Windows C ++ / CLI фактически компилируется как управляемый код, запускаемый CLR, который выполняет собственный код; поскольку в Mac OS Mono не интегрирован в систему, скорее наоборот. Ваше приложение является нативным и может содержать управляемый код.

Mono предоставляет функции для размещения виртуальной машины CLR внутри процесса. Так как классы CLR напрямую не представлены вашему коду C, вы сможете вызывать методы объектов с помощью вызовов, похожих на отражения.

На официальном сайте есть документация о том, как встроить Mono в приложение . Поскольку вас не интересует прямой запуск программ .NET , вам лучше прочитать раздел «Методы вызова в CIL Universe» . В Mac OS вам нужно будет ссылаться на платформу Mono из папки /Library/Frameworks вместо использования pkg-config.

Это действительно не должно заменять фактическое прочтение вышеуказанного документа, но следующее может рассматриваться как руководство относительно того, чего ожидать:

#include <glib/glib.h>
#include <mono/jit/jit.h>
#include <mono-metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>

// create an app domain
// http://en.wikipedia.org/wiki/Application_Domain
MonoDomain* domain = mono_jit_init("Domain");

// mandatory Cocoa call to show that Mono and ObjC work together
NSBundle* mainBundle = [NSBundle mainBundle];
NSString* dll = [mainBundle pathForResource:@"your-dll" ofType:@"dll"];

// load the referenced assembly in our domain
MonoAssembly* assembly = mono_domain_assembly_open(domain, [dll UTF8String]);
MonoImage* image = mono_assembly_get_image(assembly);

// find the class we want to wrap and create an uninitialized instance
MonoClass* classHandle = mono_class_from_name(image, "Name.Space", "YourClass");
MonoObject* object = mono_object_new(domain, classHandle);

// this calls the default, argument-less ctor
// for more complex constructors, you need to find the method handle and call it
// (helpful hint: constructors are internally called ".ctor", so the description
// string will look like "Namespace.Class..ctor()")
mono_runtime_object_init(object);

// get a method handle to whatever you like
const char* descAsString = "Your.NameSpace.YourClass:YourMethod()";
MonoMethodDesc* description = mono_method_desc_new(descAsString);
MonoMethod* method = mono_method_desc_search_in_class(description, classHandle);

// call it
void* args[0];
mono_runtime_invoke(method, object, args, NULL);

// when you're done, shutdown the runtime by destroying the app domain
mono_jit_cleanup(domain);

Если вы не находите это очень привлекательным вы можете пойти другим путем, как вы упомянули, и обратиться к MonoMac , который предоставляет привязки .NET к большой части API, которые вы можете использовать в приложении Mac (Какао, CoreImage, CoreAnimation и т. Д.) И средства для создания собственных привязок.

16
ответ дан 28 November 2019 в 02:07
поделиться

Если вы делаете это на Mac, то да, это возможно. На iOS не так уж и много.

На Mac, если вы можете создать приложение CLI в MonoMac, то вы можете вызывать свое приложение CLI из приложения Objective-C с помощью NSTask. NSTask позволяет легко запускать инструмент командной строки, а затем записывать его результаты и взаимодействовать с ним. Чтобы сделать это, вы должны сделать что-то вроде:

NSArray *args = [NSArray arrayWithObjects:@"-arg1", @"-arg2", nil];
NSTask *foo = [[NSTask alloc] init];
[foo setLaunchPath:@"/usr/bin/foo"];
[foo setArguments:args];

NSPipe *pipe = [NSPipe pipe];
[foo setStandardOutput:pipe];

NSFileHandle *output = [pipe fileHandleForReading];

[foo launch];

NSData *data = [output readDataToEndOfFile];

NSString *outputStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(@"Got stuff: %@", outputStr);

Как правило, то, как вы хотите это сделать, это включить приложение CLI в свой пакет приложений. Затем вы можете получить путь к приложению CLI, используя NSBundles -pathForResource: ofType: метод.

iOS не включает NSTask API, поэтому это невозможно. Я слышал о некоторых людях, использующих MonoTouch для создания приложений для iOS с использованием C #, но, как вы и предлагали, я думаю, что вам лучше придерживаться Objective-C для большей части вашего приложения, если это возможно. Использование приложения CLI, которое вы описываете, определенно является опцией для Mac и может быть особенно полезно, когда у вас есть фрагмент кода, который уже написан и протестирован и работает, который вы просто хотите "обернуть" с помощью графического интерфейса Какао.

Итак, NSTask - это один из способов сделать это, используя внешний исполняемый файл CLI, обернутый в комплект вашего приложения. С другой стороны, вам может быть интересно, можете ли вы связать свой код C # непосредственно с Objective-C?

Ну, Objective-C является надмножеством C, и поэтому обладает всеми возможностями C Кроме того, если вы используете Objective-C ++, он также обладает всеми возможностями C ++. Итак, ЕСЛИ вы можете заставить MonoMac генерировать статическую библиотеку на C или C ++, тогда да, вы можете просто связать свою статическую библиотеку с вашим кодом Objective-C, и это будет работать. Я не могу рассказать вам, как сделать библиотеку из MonoMac, но связать ее - просто добавить ее в ваши связанные библиотеки в настройках сборки в XCode.

РЕДАКТИРОВАТЬ: Я не знаком с C ++ / CLI как языком, и я неверно истолковал значение C ++ / CLI для обозначения «Приложение интерфейса командной строки C ++». Тем не менее ... методы, которые я описал, по-прежнему применяются в качестве возможных методов для выполнения того, что вы хотите сделать, но он НЕ использует интерфейс C ++ / CLI, как в Windows.

3
ответ дан 28 November 2019 в 02:07
поделиться