[Mono-list] DllImport and modifying library search path

Uli Hertlein uli at xdt.com.au
Mon Feb 14 02:15:48 EST 2011


Hi guys,

On 02/11/2011 08:25 PM, Robert Jordan wrote:
> On 11.02.2011 08:26, Uli Hertlein wrote:
>> Now, to pickup the correct shared library I thought I'd prefix the the respective search path
>> (LD_LIBRARY_PATH on Linux, DYLD_LIBRARY_PATH on OS X, and PATH on Windows) with this directory.
>> This is then set using 'Environment.SetEnvironmentVariable("LD_LIBRARY_PATH", dllSearchPath)'
>
> You're probably calling one of the p/invokes too close
> to SetEnvironmentVariable (called either directly or indirectly).
>
> If you really want such a fragile hack (it depends on the
> order and the moment a method is JITed), you should compute
> the variable that keeps the OS and bitness "far away" from
> the first p/invoke call.
>...
> Anything else is just a huge hack and big waste of time, IMO.

Huge - hopefully not.
Waste of time - possibly ;-)
I acknowledge that the intended usage is probably not the right way to do it.

But the basic issue is still stands: I can set the LD_LIBRARY_PATH to complete garbage from within 
Mono but dlopen (and hence DllImport?) just ignores it.  It's almost like the dlopen is executed 
from another process, and so doesn't pick up the changed environment variable.

(I'm not saying this is an error, I'm just after clarification.)

$ /usr/local/mono/bin/mono dlopen.exe
***** Main
***** LD_LIBRARY_PATH=DoesNotExist
dll libSdk.so failed to load: libSdk.so: cannot open shared object file: No such file or directory

$ LD_LIBRARY_PATH=Linux64 /usr/local/mono/bin/mono dlopen.exe
***** Main
***** LD_LIBRARY_PATH=DoesNotExist
dll libSdk.so loaded, handle 15682432

<code>
namespace dlopen
{
     using System;
     using System.Runtime.InteropServices;

     class Program
     {
         // dlopen(3)
         [DllImport("libdl.so", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
         private static extern IntPtr dlopen(string filename, int flags);

         // dlerror(3)
         [DllImport("libdl.so", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
         private static extern string dlerror();

         static void Main(string[] args)
         {
             try
             {
                 Console.WriteLine("***** Main");

                 // Overwrite search path
                 Environment.SetEnvironmentVariable("LD_LIBRARY_PATH", "DoesNotExist");
                 Console.WriteLine("***** LD_LIBRARY_PATH={0}", 	
			Environment.GetEnvironmentVariable("LD_LIBRARY_PATH"));

                 // Load the shared library in "Linux64/libSdk.so"
                 IntPtr handle = dlopen("libSdk.so", 0x02);
                 Console.WriteLine("handle={0}", handle);
                 if (handle == IntPtr.Zero)
                 {
                     Console.WriteLine("dlerror={0}", dlerror());
                 }
             }
             catch (Exception ex)
             {
                 Console.WriteLine(ex);
             }
         }
     }
}
</code>


-- 
Ulrich Hertlein
Research and Development   mailto:uli at xdt.com.au
XDT Pty Ltd                http://www.xdt.com.au


More information about the Mono-list mailing list