Monotouch PInvoke System.EntryPointNotFoundException
我已经使用monotouch将一些C#代码嵌入到iPhone Objective-C应用程序中.我可以调用C#代码并获取返回值,但是我无法使用PInvoke从C#代码中调用C函数.我正在尝试一个简单的例子.这是一个简单的计算器.目标C代码调用C#代码以添加两个整数.然后,C#代码应回调到Objective-C代码并为其提供更新后的值.下面是处理计算的C#代码:
I've embedded some C# code into an iphone objective-c app using monotouch. I'm able to call into the C# code and get a return value, but I am not able to invoke a C function from the C# code using PInvoke. I am attempting to get a trivial example working. It is a simple calculator. The objective c code calls into the C# code to add two integers. The C# code should then call back into the objective-c code and give it the updated value. Below is the C# code that handles the calculation:
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);
}
这是我的代码,用于初始化mono并处理add方法:
Here is my code that initializes mono and handles the add method:
@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方法的定义:
and here is the definition of the updateResults method:
extern void updateResult(int result) {
printf("Got Result");
}
从C#端调用updateResults时,出现以下异常:
When the updateResults is called from the C# side of things I get the following exception:
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
我可以使用以下命令在二进制文件中看到该符号:
I can see the symbol in the binary with the following command:
$ nm Calc | grep updateResult
00002b2e t _updateResult
设置MONO_LOG_LEVEL环境变量以进行调试尝试PInvoke时得到以下输出.看起来好像找到了方法,然后找不到了:
Setting the MONO_LOG_LEVEL environment variable to debug I get the following output when attempting the PInvoke. It looks like it finds the method and then can't find it:
Mono:DllImport尝试加载:'_ Internal'.Mono:搜索'updateResult'.Mono:探测'updateResult'.Mono:探测'updateResult'.Mono:探测'updateResultA'.Mono:探测'updateResultA'.Mono:DllImport尝试加载:' _Internal'.Mono:搜索'updateResult'.Mono:探测'updateResult'.Mono:探测'updateResult'.Mono:探测'updateResultA'.Mono:探查'updateResultA'.Mono:AOT找到了AOT编译的代码,用于(包装器托管到本机)Math.MyClass:updateResult(int)0x3bc8-0x3d90 0x3dcb
Mono: DllImport attempting to load: '_Internal'.Mono: Searching for 'updateResult'.Mono: Probing 'updateResult'.Mono: Probing 'updateResult'.Mono: Probing 'updateResultA'.Mono: Probing 'updateResultA'.Mono: DllImport attempting to load: '_Internal'.Mono: Searching for 'updateResult'.Mono: Probing 'updateResult'.Mono: Probing 'updateResult'.Mono: Probing 'updateResultA'.Mono: Probing 'updateResultA'.Mono: AOT FOUND AOT compiled code for (wrapper managed-to-native) Math.MyClass:updateResult (int) 0x3bc8 - 0x3d90 0x3dcb
Mono:DllImport尝试加载:'__Internal'.Mono:搜索'updateResult'.Mono:探测'updateResult'.Mono:探测'updateResult'.Mono:探测'updateResultA'.Mono:探测'updateResultA'.无法解析pinvoke方法'Math.MyClass:updateResult(int)',请重新运行MONO_LOG_LEVEL = debug以获取更多信息.
Mono: DllImport attempting to load: '__Internal'.Mono: Searching for 'updateResult'.Mono: Probing 'updateResult'.Mono: Probing 'updateResult'.Mono: Probing 'updateResultA'.Mono: Probing 'updateResultA'.Unable to resolve pinvoke method 'Math.MyClass:updateResult (int)' Re-run with MONO_LOG_LEVEL=debug for more information.
我花了很多时间试图解决这个问题.从我阅读的内容来看,这似乎是微不足道的,但我无法使其正常工作.任何帮助将不胜感激.
I've spent quite some time trying to figure this out. From what I've read it seems like this should be pretty trivial, but I can't get it to work. Any help would be much appreciated.
使用选择器?
这是MonoTouch制造商建议的默认路径.
That is the default path to follow as suggested by the makers of MonoTouch.