Monotouch PInvoke System.EntryPointNotFoundException - PullRequest
3 голосов
/ 23 февраля 2011

Я встроил некоторый код C # в приложение iphone target-c, используя monotouch. Я могу вызвать код C # и получить возвращаемое значение, но я не могу вызвать функцию C из кода C # с помощью PInvoke. Я пытаюсь заставить работать тривиальный пример. Это простой калькулятор. Целевой код c вызывает в коде C #, чтобы добавить два целых числа. Затем код C # должен перезвонить в код target-c и присвоить ему обновленное значение. Ниже приведен код C #, который обрабатывает вычисления:

public class MyClass
{       
    static public void Add(int a, int b)
    {
        updateResult(a + b);
    }

    [DllImport("__Internal", EntryPoint="updateResult")]
    static extern public void updateResult(int result);
}

Вот мой код, который инициализирует моно и обрабатывает метод add:

@implementation Mono

- (id)init {
self = [super init];

if (self) {
    NSBundle *main = [NSBundle mainBundle];
    NSString *path = [main bundlePath];
    const char *c_path = [path UTF8String];

    [main autorelease];
    [path autorelease];

    chdir (c_path);
    setenv ("MONO_PATH", c_path, 1);
    setenv ("MONO_XMLSERIALIZER_THS", "no", 1);
    setenv ("DYLD_BIND_AT_LAUNCH", "1", 1);
    setenv ("MONO_REFLECTION_SERIALIZER", "yes", 1);

#if defined (__arm__)
    mono_aot_register_module (mono_aot_module_mscorlib_info);
    mono_aot_register_module (mono_aot_module_Math_info);

    mono_jit_set_aot_only (TRUE);
#endif
    mono_jit_init("MonoTouch");
    MonoAssembly *assembly = mono_assembly_open("Math.dll", NULL);
    MonoImage *img = mono_assembly_get_image(assembly);
    MonoClass *cls = mono_class_from_name(img, "Math", "MyClass");
    MonoMethodDesc *methodDesc = mono_method_desc_new("Math.MyClass:Add", TRUE);
    _addMethod = mono_method_desc_search_in_class(methodDesc, cls);
}

return self;
} 

- (void)addA:(int)a plusB:(int)b {
    void *params[] = { &a, &b };
    mono_runtime_invoke(_addMethod, NULL, params, NULL);
}

@end

и вот определение метода updateResults:

extern void updateResult(int result) {
    printf("Got Result");
}

Когда updateResults вызывается со стороны C #, я получаю следующее исключение:

Unhandled Exception: System.EntryPointNotFoundException: updateResult
at (wrapper managed-to-native) Math.MyClass:updateResult (int)
at Math.MyClass.Add (Int32 a, Int32 b) [0x00000] in <filename unknown>:0 

Я могу увидеть символ в двоичном коде с помощью следующей команды:

$ nm Calc | grep updateResult
00002b2e t _updateResult

Установка отладки переменной среды MONO_LOG_LEVEL Я получаю следующий вывод при попытке PInvoke. Похоже, что он находит метод, а затем не может его найти:

Моно: DllImport пытается загрузить: '_ Внутренний'. Моно: Поиск 'updateResult'. Моно: Зондирование 'updateResult'. Моно: Зондирование 'updateResult'. Моно: Зондирование 'updateResultA'. Моно: Зондирование 'updateResultA'.Mono: DllImport пытается загрузить:' _Internal'.Mono: поиск 'updateResult'. Моно: Зондирование 'updateResult'.Mono: Зондирование' updateResult'.Mono: Зондирование 'updateResultA'. 'updateResultA'.Mono: AOT НАЙДЕН AOT-скомпилированный код для (управляемого для оболочки) Math.MyClass: updateResult (int) 0x3bc8 - 0x3d90 0x3dcb

Моно: DllImport пытается загрузить: '__Internal'. Моно: Поиск 'updateResult'. Моно: Зондирование 'updateResult'. Моно: Зондирование 'updateResult'. Моно: Зондирование 'updateResultA'. Моно: Зондирование 'updateResultA'. Не удалось разрешить метод pinvoke 'Math.MyClass: updateResult (int)'. Повторно запустите с MONO_LOG_LEVEL = debug для получения дополнительной информации.

Я потратил довольно много времени, пытаясь понять это. Из того, что я прочитал, кажется, что это должно быть довольно тривиально, но я не могу заставить его работать. Любая помощь будет высоко ценится.

Ответы [ 3 ]

1 голос
/ 23 февраля 2011

Было бы лучше использовать Селекторы ?

Это путь по умолчанию, предложенный создателями MonoTouch.

1 голос
/ 10 марта 2012

Я сам столкнулся с этой проблемой, если вы сравните objdump -T и objdump -t вашего двоичного файла, вы обнаружите, что флаг "D" отсутствует, поэтому добавьте -rdynamic к параметрам компоновщика.

1 голос
/ 23 февраля 2011

Это может быть несколько вещей, но я предполагаю, что вы не используете символ C нигде в нативном коде, и проход DCE (удаление мертвого кода) удаляет его. Попробуйте отключить DCE в настройках вашего проекта Xcode.

...