Unable to load dynamic library(DYLIB) in MacOS
Asked Answered
G

3

7

I am trying to load a library(say ArithmeticOprn.dylib) dynamically and call the methods presented within that library. Please refer to the sample code snippet from below,

[DllImport("libdl.dylib")]
public static extern IntPtr dlopen(String fileName, int flags);

[DllImport("ArithmeticOprn.dylib")]
public static extern double Add(double a, double b);

static void Main(string[] args)
{
    dlopen("path/to/ArithmeticOprn.dylib", 2);
    double result = Add(1, 2);
}

While running the above sample in MacOS, I got the following exception:

Unable to load DLL "ArithmeticOprn.dylib": The specified module or one of its dependencies could not be found.

But, when I provide full path in the DllImport the method call works and I can get the expected results. For your reference, please refer below for the code snippet.

[DllImport("path/to/ArithmeticOprn.dylib")]
public static extern double Add(double a, double b);

Could you please let me know what I am missing ? Thanks in advance :)

Greensward answered 23/11, 2018 at 11:54 Comment(7)
Similar questions found #12036957 #21577627Rox
@Rox There's no answer found in it.Greensward
Yes. That's why added +1Rox
@Rox - yes he is right no answer is found.Zandrazandt
What language is this? C#?Sandstorm
Yes, it is C# @SandstormGreensward
You should run otool -L (this is the (kind of) OSXs equivalent for ldd) on your lib, and check which dependencies are not found and why. Could be that they are present, but they target a different architecture.Tomasz
C
1

It is a bit late but I recently ran into similar issue myself and maybe that will save some time for others looking for answers.

It is good to have in mind what @CristiFati suggested in the comment - the lib in general might have targeted different arch, but as you said it is loading when given a full path so I think the arch is correct.

It would be interesting to know whether you use Xamarin.Mac or raw mono to run your application as they link libraries differently.

For Xamarin.Mac I answered here - you should use

  <ItemGroup>
    <BundleResource Include="<path-to>ArithmeticOprn.dylib" />
  </ItemGroup>

in your *.csproj - it will add this native lib to the mono bundle created in process of compilation.

Where is for mono you would either need to:

  1. do what @Petesh suggested in the answer above

  2. create a symbolic link before running the app, like:

    ln -sf ArithmeticOprn.dylib <path-to>ArithmeticOprn.dylib

  3. add app.config to your project which would do similar thing what 2) does, like:

    <?xml version="1.0" encoding="utf-8"?>
     <configuration>
      <dllmap os="osx" dll="ArithmeticOprn.dylib" target="path/to/ArithmeticOprn.dylib"/>
    </configuration>

Hope that might help anyone being in pickle like me, good luck!

Conchaconchie answered 11/11, 2020 at 14:3 Comment(0)
K
1

I was recently stuck with this problem. I solved it by adding my .dylib file in Targets > Build Phases > Embed Frameworks (it works on simulator, I am not able to make it work on ios device though)

imported lib5.dylib

and then importing it like -

[DllImport("lib5.dylib", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
static extern int test(string s);
Karenkarena answered 9/12, 2022 at 19:29 Comment(0)
P
0

You're trying to short-cut the DllImport behaviour through an explicit dlopen - i.e. using the dlopen to specify the path that's supposed to be used by the DllImport. The problem is that the DllImport link-up is done internally to the C# run-time before the dlopen gets called.

the dlopen never gets a look in.

In order to use DllImport without a path, you need to rely on the default search behaviour, which is locations as specified by the environment variables $LD_LIBRARY_PATH, $DYLD_LIBRARY_PATH, current working directory, $DYLD_FALLBACK_LIBRARY_PATH.

So, for example:

env DYLD_LIBRARY_PATH=path/to/ mono test.exe

which runs the mono interpreter with the path pre-loaded with path/to, allowing it to find the dylib in that location.

Other solutions include moving the library into the directory with the executable, making a symlink to the library in the current working directory.

Pregnant answered 26/11, 2018 at 16:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.