您好我试图将谷歌admboads更新为V6但是我遇到一些麻烦来绑定以下内容并将其暴露给托管世界
我有以下结构
typedef struct GADAdSize {
CGSize size;
NSUInteger flags;
} GADAdSize;
我在monotouch方面这样做了
[StructLayout(LayoutKind.Sequential)]
public struct GADAdSize
{
public SizeF size;
public uint flags;
}
我有以下代码
extern GADAdSize const kGADAdSizeBanner;
extern GADAdSize const kGADAdSizeMediumRectangle;
我不能使用[Field]属性绑定它,因为docs指定Field属性只能用于
所以我尝试了以下两种我能想到的方法
[DllImport ("__Internal")]
extern static IntPtr kGADAdSizeMediumRectangle ();
public static GADAdSize MediumRectangle
{
get
{
object obj = Marshal.PtrToStructure(kGADAdSizeMediumRectangle(), typeof(GADAdSize));
return (GADAdSize) obj;
}
}
和
public static GADAdSize Banner
{
get
{
var handle = Dlfcn.dlopen ("libGoogleAdMobAds", 0);
IntPtr ptr = Dlfcn.GetIntPtr(handle, "kGADAdSizeBanner");
Dlfcn.dlclose (handle);
object obj = Marshal.PtrToStructure(ptr, typeof(GADAdSize));
return (GADAdSize) obj;
}
}
并且两种方式崩溃
使用DLLImport我在调用Marshal.PtrToStructure()时得到一个nullargugument异常,第二个异常引发 DLLNotFoundException System.ArgumentNullException
提前感谢您提供任何帮助
Alex
编辑:
抱歉@Poupou我的不好,它抛出一个System.ArgumentNullException的句柄值,它的0也是ptr值为0
并且堆栈跟踪是:
System.ArgumentNullException: Argument cannot be null.
Parameter name: src
at (wrapper managed-to-native) System.Runtime.InteropServices.Marshal:PtrToStructure (intptr,System.Type)
at AlexTouch.GoogleAdMobAds.GADAdSizeConstants.get_Banner () [0x00000] in <filename unknown>:0
at MobclixText.MobclixTextViewController.ViewDidLoad () [0x00006] in /Users/Alex/Projects/MobclixText/MobclixText/MobclixTextViewController.cs:33
at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:void_objc_msgSend (intptr,intptr)
at MonoTouch.UIKit.UIWindow.MakeKeyAndVisible () [0x00010] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIWindow.g.cs:98
at MobclixText.AppDelegate.FinishedLaunching (MonoTouch.UIKit.UIApplication app, MonoTouch.Foundation.NSDictionary options) [0x00031] in /Users/Alex/Projects/MobclixText/MobclixText/AppDelegate.cs:44
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
at MobclixText.Application.Main (System.String[] args) [0x00000] in /Users/Alex/Projects/MobclixText/MobclixText/Main.cs:17
我想这是因为处理为0。
关于您的评论
将dlsym与其中一个特殊标志(man dlsym)一起使用可能有所帮助。
你能给我一个如何使用它的例子,请=)??
亚历
编辑2:
您好@Poupou并感谢您的回答,但是
IntPtr RTLD_MAIN_ONLY = (IntPtr) (-5);
IntPtr ptr = Dlfcn.GetIntPtr (RTLD_MAIN_ONLY, "kGADAdSizeBanner");
我仍然得到ptr
等于0
任何其他想法?
Alex
编辑3:
好的,我现在尝试以下
IntPtr RTLD_MAIN_ONLY = Dlfcn.dlopen (null, 0);
IntPtr ptr = Dlfcn.dlsym (RTLD_MAIN_ONLY, "kGADAdSizeBanner");
Console.WriteLine("RTLD_MAIN_ONLY: " + RTLD_MAIN_ONLY);
Console.WriteLine("ptr: " + ptr);
Dlfcn.dlopen (null, 0);
完成here现在我得到一个句柄值-2
但是我想原生链接器它现在正在删除符号,我该怎样才能防止这种情况发生?< / p>
非常感谢你@Poupou的时间
亚历
答案 0 :(得分:4)
所以我找到了获得价值的方法。第一部分是说服链接器导出符号(不隐藏任何现有符号)。这可以通过创建(本地)符号的别名(默认情况下是全局的)来完成。 E.g。
-gcc_flags="-Xlinker -alias -Xlinker _kGADAdSizeBanner -Xlinker _MTAdSizeBanner"
之后的代码:
IntPtr RTLD_MAIN_ONLY = Dlfcn.dlopen (null, 0);
IntPtr ptr = Dlfcn.dlsym (RTLD_MAIN_ONLY, "MTAdSizeBanner");
object obj2 = Marshal.PtrToStructure(ptr, typeof(GADAdSize));
将为您提供GADAdSize
的实例,其值为320x50。
您需要重新导出所需的每个符号(yuck),但应该可以将其包含在[LinkWith]
属性(iirc)中,因此对最终用户来说不是必需的。< / p>
答案 1 :(得分:1)
您的第二个解决方案是通常使用的内容。它动态加载指定库中的符号。 OTOH对iOS上的系统库只有 。
为什么?因为您自己提供的库将与您的主可执行文件静态链接。这与[DllImport("__Internal")
必须用于正常p / invoke的原因相同。
回到符号,dldym
有一些选项可以处理主可执行文件(或所有加载的代码)。在终端窗口上执行man dlsym
以查看它们。那可能(没试过)使用:
IntPtr RTLD_MAIN_ONLY = (IntPtr) -5;
IntPtr ptr = Dlfcn.GetIntPtr (RTLD_MAIN_ONLY, "kGADAdSizeBanner");
注1:Dlfcn.GetIntPtr
是一种基本上包裹dlsym
;
注意2:看看其他选项:-)如果你得到一个非空(不是IntPtr.Zero
)指针,那么你可以尝试将它编组成SizeF
结构。