Hello im trying to update google admboads to V6 but im having some trouble to bind the following and expose it to managed world
I have the following struct
typedef struct GADAdSize {
CGSize size;
NSUInteger flags;
} GADAdSize;
and I did this on monotouch side
[StructLayout(LayoutKind.Sequential)]
public struct GADAdSize
{
public SizeF size;
public uint flags;
}
I have the following code
extern GADAdSize const kGADAdSizeBanner;
extern GADAdSize const kGADAdSizeMediumRectangle;
I can't bind it using [Field] Attribute since docs specify that Field attribute can only be used for
So I tried the following 2 ways i could think of
[DllImport ("__Internal")]
extern static IntPtr kGADAdSizeMediumRectangle ();
public static GADAdSize MediumRectangle
{
get
{
object obj = Marshal.PtrToStructure(kGADAdSizeMediumRectangle(), typeof(GADAdSize));
return (GADAdSize) obj;
}
}
and
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;
}
}
And on both ways it crashes
Using the DLLImport I get a nullargument exception when calling Marshal.PtrToStructure() and the second one rises an DLLNotFoundException System.ArgumentNullException
Thanks in advance for any help
Alex
Edit:
Sorry @Poupou my bad, it throws a System.ArgumentNullException the handle value its 0 also the ptr value its 0
and the stacktrace is:
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
I guess this is due to handle being 0.
About your comment
Using dlsym with one of the special flags (man dlsym) might help.
Could you provide me an example on how to use it please =) ??
Alex
Edit 2:
Hello @Poupou and thanks for your answer, but with
IntPtr RTLD_MAIN_ONLY = (IntPtr) (-5);
IntPtr ptr = Dlfcn.GetIntPtr (RTLD_MAIN_ONLY, "kGADAdSizeBanner");
I still get ptr equals to 0 any other idea??
Alex
Edit 3:
Ok, im trying the following now
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); as its done here now I'm getting a handle value -2 but I guess native linker it's removing the symbol now, how can I prevent this from happening??
Thanks a lot for your time @Poupou
Alex
Your second solution is what is normally used. It dynamically loads the symbols from the specified library. OTOH this works only for system libraries on iOS.
Why ? because your own supplied libraries will be linked statically with your main executable. That's the same reason that [DllImport("__Internal") must be used for normal p/invoke.
Back to symbols, dldym has some options to work on the main executable (or all loaded code). Do a man dlsym on a terminal window to see them. That might (did not try it) work using:
IntPtr RTLD_MAIN_ONLY = (IntPtr) -5;
IntPtr ptr = Dlfcn.GetIntPtr (RTLD_MAIN_ONLY, "kGADAdSizeBanner");
Note 1: Dlfcn.GetIntPtr is an utility method that basically wraps dlsym;
Note2: look at the other options as well :-) If you get a non-null (not IntPtr.Zero) pointer then you can try to marshal it into a SizeF structure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With