Having a frustrating and probably basic problem with linking in native lib

The eventual long-term plan is to wrap some existing native libraries with C# wrappers, but for now I am just trying to write a simple library in Xcode and use it from a Xamarin iOS project. I am reasonably competent on the windows/c# side but am fairly new to Mac, iOS, and Xamarin, so my problem likely lies somewhere in my lack of experience. On the C/XCode side, I have a simple .h and .cpp file that defines the following function:

extern "C" int __stdcall TestExport()
{
return 10;
}

and on the C#/Xamarin side, I bind it with:
public static class Tests
{
[DllImport ("__Internal",EntryPoint="TestExport",CallingConvention = CallingConvention.StdCall)]
public extern static int TestExport();
}

The only thing different in this from a working windows project is the change to "__Internal" from the dll name, and the lack of __declspec(dllexport) on the C side, which I do not see an equivalent for, so I have assumed it isn't needed.

I am getting a System.EntryPointNotFound exception, which should indicate that the lib is being loaded correctly, but the actual function name is not found.

Other notes: I am using the lipo with makefile as specified in the tutorials to build both i386 and arm versions of the lib and lipo-ing them together. I have also tried both adding the lib as a link and with deleting and adding a copy of the lib to no avail. I do not currently know of a tool equivalent to dumpbin that might show me the names available in the lib, so I'm not sure if it's a problem on the export side or on the import side.

Thanks for any help.

Posts

  • ChrisOatesChrisOates USMember

    sorry for bad formatting of above! trying again:

    function on C/XCode side:

    extern "C" int __stdcall TestExport()
    {
        return 10; 
    }
    

    binding on c#/Xamarin side:

    public static class Tests
    {
        [DllImport ("__Internal",EntryPoint="TestExport",CallingConvention = CallingConvention.StdCall)]
        public extern static int TestExport();
    }
    
  • Is there anything you've done in addition to creating the library and interop call?

    One key thing you need to do is tell the Xcode linker to force load the native library so that the app can find it at run-time. See the section "Linking Your Library" [1] in the Xamarin.iOS documentation for details.

    Without force loading the library, the linker will see your native function as dead code (since no one is directly calling it) and will remove it. When the app goes to call it, it dynamically tries to load it and won't be able to find it; thus, the app sees an EntryPointNotFound exception.

    [1] Linking Native Libraries http://docs.xamarin.com/guides/ios/advanced_topics/native_interop

  • ChrisOatesChrisOates USMember

    That was it, thanks! I was pretty sure that it would be something basic that I just missed in the docs. Next up is to put this into a simple binding project rather than link in directly to my app, so I may have more questions.

  • ChrisOatesChrisOates USMember

    Okay, so the binding project does not work if I put my declaration into ApiDefinition.cs, but it does if I put it into another file in the binding project. Is ApiDefinition.cs treated differently than other .cs files?

    The error is that the application project cannot see anything I declare in ApiDefinition.cs, so I get compile errors.

  • ChrisOatesChrisOates USMember

    ...And I may have answered my own question. ApiDefinition.cs is marked as "ObjCBindingApiDefinition" in build action and not "compile" -- saw the doc page that explains the difference. No more questions for now.

Sign In or Register to comment.