I went through the documentation for doing Xamarin binding for Zendesk SDK for IOS. The documentation takes us through the scenario where we create .a file and proceed with binding. Zendesk library is provided in the form of a framework and though the Xamarin documentation says that frameworks contain .a file, I still could not find .a file in Zendesk framework. Hence, I am kind of blocked here. Any pointers here?
Link to Zendesk Library : https://github.com/zendesk/zendesk_sdk_ios
Link to Xamarin documentation : https://learn.microsoft.com/en-us/xamarin/ios/platform/binding-objective-c/walkthrough?tabs=vsmac
I ran objective sharpie command. Though it says binding is done, it did not generate apidefinition.cs and structsAndEnums.cs file . Following is the output I see in terminal.
C02VX2ZCHTD6:~ naveen.ramachandrapp$ sharpie bind -output=Zen -namespace=zen -sdk iphoneos11.3 -framework /Users/naveen.ramachandrapp/Downloads/zendesk_sdk_ios-masterObjectiveC/ZendeskSDK/4.1/ZendeskProviderSDK.framework
Parsing 1 header files...
Binding...
[write] ApiDefinitions.cs
[write] StructsAndEnums.cs
Binding Analysis:
Automated binding is complete, but there are a few
APIs which have been flagged with [Verify]
attributes. While the entire binding should be
audited for best API design practices, look more
closely at APIs with the following Verify attribute
hints:
MethodToProperty (30 instances):
An Objective-C method was bound as a C# property
due to convention such as taking no parameters and
returning a value (non-void return). Often methods
like these should be bound as properties to
surface a nicer API, but sometimes false-positives
can occur and the binding should actually be a
method.
StronglyTypedNSArray (25 instances):
A native NSArray* was bound as NSObject[]. It
might be possible to more strongly type the array
in the binding based on expectations set through
API documentation (e.g. comments in the header
file) or by examining the array contents through
testing. For example, an NSArray* containing only
NSNumber* instances can be bound as NSNumber[]
instead of NSObject[].
ConstantsInterfaceAssociation (2 instances):
There's no foolproof way to determine with which
Objective-C interface an extern variable
declaration may be associated. Instances of these
are bound as [Field] properties in a partial
interface into a nearby concrete interface to
produce a more intuitive API, possibly eliminating
the 'Constants' interface altogether.
PlatformInvoke (3 instances):
In general P/Invoke bindings are not as correct or
complete as Objective-C bindings (at least
currently). You may need to fix up the library
name (it defaults to '__Internal') and return/
parameter types manually to conform to C calling
conventionsfor the target platform. You may find
you don't even want to expose the C API in your
binding, but if you do, you'll probably also want
to relocate the definition to a more appropriate
class and expose a stronger type-safe wrapper. For
P/Invoke guidance, see http://www.mono-project.com/
docs/advanced/pinvoke/.
Once you have verified a Verify attribute, you
should remove it from the binding source code. The
presence of Verify attributes intentionally cause
build failures.
For more information about the Verify attribute
hints above, consult the Objective Sharpie
documentation by running 'sharpie docs' or visiting
the following URL:
http://xmn.io/sharpie-docs
You have misread the documentation. It clearly lists 3 different scenarios:
Generally in the iOS ecosystem you can find libraries in 3 flavors:
As a precompiled static library file with .a extension together with
its header(s) (.h files). For example, Google’s Analytics Library
As a precompiled Framework. This is just a folder containing the static
library, headers and sometimes additional resources with .framework
extension. For example, Google’s AdMob Library.
As just source code files. For example, a library containing just .m and .h Objective C
files.
So you can create binding libraries using a .a file or a precompiled .framework (your case) or using .h and .m files. No need to look for .a files in the .framework file.
You can use objective sharpie to help create a ApiDefinition.cs file for your binding like so:
sharpie bind -framework ZendeskCoreSDK.framework -sdk iphoneos11.1
There is loads of documentation for Objective Sharpie here: https://learn.microsoft.com/en-us/xamarin/cross-platform/macios/binding/objective-sharpie/
Related
In my Xamarin.iOS project I need to reduce the assembly size (Apple's requirement for AppStore applications), and I need to turn on linker, setting the linker behavior either to "Link Framework SDKs only" or "Link All".
When I've selected "Link Framework SDKs only" in Linker behavior I get the compilation error upon building the project:
Can't resolve the reference 'System.Void System.Data.SqlClient.SqlCommandBuilder::DeriveParameters(System.Data.SqlClient.SqlCommand)',
referenced from the method 'System.Void DevExpress.Xpo.DB.MSSqlConnectionProvider::CommandBuilderDeriveParameters(System.Data.IDbCommand)'
in 'System.Data.SqlClient, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
To fix this issue all answers I have found recommendation to turn "Link All" option in the Linker behavior option.
When I've selected "Link All", the project compiles okay, but at the runtime I get system exception on the IoC Container code (type AAA does not implement the interface BBB), because I use reflection, and linker with "Link All" options affects the code with the reflection. And as far as I know this linker option (Link All) is not recommended for the projects where reflection is being used.
What options do I have at this point?
Linker configuration
I suspect your best option is to look at define a configuration file to tell the Linker what must be kept. There is a good set of documentation on Microsofts documentation site.
There are some other options but may not strictly apply in this case or you may wish to use a combination.
Preserve Attribute
You can provide extra definitions to the linker to ensure the type, methods and/or fields are not eliminated from your application. In your own code the preferred way is to use the [Preserve] custom attribute, as discussed in the Linking on iOS and Linking on Android guides.
Linking for each platform is certainly a possibility however I suspect that you want to preserve things in your shared project which is why I think the config file will be right for you.
This approach gives you the ability to define at varying levels (e.g. assembly or class level to keep everything or down to individual properties/methods, etc.).
Actually reference the bits you need kept
I dislike this option very much but some people find it quick and easy to either prove you can keep parts of the code or just accept it is a solution.
You essentially create a class of actual references to the methods/properties that you want to be kept.
public class LinkerPleaseInclude
{
public void Include(MyType arg)
{
arg.MethodIDontWantRemoved();
}
}
Note I have sourced some details from this site
I am attempting to write a kernel extension (kext) that uses some parts of the Kernel framework.
I added Kernel.framework to the list of Frameworks and Libraries in the target settings.
However, when I try to build my kext and link against it, Xcode refuses to do this and claims to not be able to find the framework, even though it had shown up in the list of available frameworks.
Am I doing this wrong? Is it not possible to use this framework even for kexts?
Edit: I am aware of the user space alternatives to kexts but these don't fulfill my needs.
The Kernel.framework is a header-only "framework". Kext linking is fundamentally different from user space executable linking, as there's no dyld. You don't need to link against any libraries at build time, but you must specify the KPIs to link against in the Info.plist file's OSBundleLibraries dictionary.
You can generate a draft of this dictionary using the following command:
kextlibs -xml -c path/to/your.kext
If using any unsupported KPIs, you'll also want to specify -unsupported. If it's complaining about symbols not being found, adding the -undef-symbols option will help with debugging.
I have asked this question on linux, but now I need the same info on macos... The question is (adapted to macos):
I am trying to create a shared library, libbar.dylib, that embeds a commercial static library (licensing is fine). The commercial library has 4 versions: libfoo-seq.a, libfoo-mt.a, libfoo-seq.dylib, and libfoo-mt.dylib (they all provide the same symbols, just the code is sequential/multi-threaded, and the lib is static/shared). Of these four I want my code always to use the sequential foo library, so when I create libbar.dylib I link together my object files and libfoo-seq.a.
The problem is that the users of my library may have already pulled in libfoo-mt.dylib by the time they pull in my libbar.dylib, thus all symbols from libfoo are already present by the time libbar.dylib is read in, so my calls to the functions in foo are resolved to the multithreaded version. At least I think this is happening. Is there any way to double check?
If this is really what is happening, I wonder how can I resolve this issue? What kind of magic flags do I need to use when I compile to create my object files and when I link my object files with libfoo-seq.a to create libbar.dylib?
My project is using ACE library, and need link another library libsdk.so, it's using another version ACE library.
The link order like : ...-lMyAce -lsdk -lAnotherAce
When application running, libsdk.so called method in MyAce(I checked the core dump), and the application crash.
If I change link order to: ...-lsdk -lAnotherAce -lMyAce
My code called method in AnotherAce, it's also crash.
If I only link my ACE, it's crash. There are some link error if only link AnotherAce.
Let the libsdk.so call its ACE library, and my code call my ACE library.
How can I resolve the problem?
The Solaris linker has an option that may help, though really redesigning your application to not need two sets of libraries with the same names in the same program
is going to be the best solution.
Direct Bindings record in each library or program which library it found a symbol in, so if libsdk.so is built with -B direct -lAnotherAce, it will record each of its references go to AnotherAce, not MyAce. You'd then link your code with -B direct -lsdk -lMyAce (do not include -lAnotherAce, as the libsdk dependencies take care of that), and your code would record that it's calls to to MyAce.
There are appear to be methods of creating a fat static library ala "http://stackoverflow.com/questions/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4". Is this recommended? Any special steps (i.e., disabling thumb)
Also, if I do use the fat static library, will monotouch/xcode clear out any unused code in the final product?
You definitely need to turn Thumb code off so you can link properly against the library. As far as creating the fat static library goes, I can only say that anecdotally I've done this for a few third-party libraries that I've used and haven't run into issues.
I assume you already know that you need to create the bindings necessary to make calls to the objective-c library from your MonoTouch code and add extra gcc flags in the project properties to link in the static lib. If not, you can get that information on how to do that from the MonoTouch website.