Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8883831
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T20:54:44+00:00 2026-06-14T20:54:44+00:00

I’m writing a cross-platform .NET library that uses some unmanaged code. In the static

  • 0

I’m writing a cross-platform .NET library that uses some unmanaged code. In the static constructor of my class, the platform is detected and the appropriate unmanaged library is extracted from an embedded resource and saved to a temp directory, similar to the code given in another stackoverflow answer.

So that the library can be found when it isn’t in the PATH, I explicitly load it after it is saved to the temp file. On windows, this works fine with LoadLibrary from kernel32.dll. I’m trying to do the same with dlopen on Linux, but I get a DllNotFoundException when it comes to loading the P/Invoke methods later on.

I have verified that the library “libindexfile.so” is successfully saved to the temp directory and that the call to dlopen succeeds. I delved into the mono source to try figure out what is going on, and I think it might boil down to whether or not a subsequent call to dlopen will just reuse a previously loaded library. (Of course assuming that my naïve swoop through the mono source drew the correct conclusions).

Here is the shape of what I’m trying to do:

// actual function that we're going to p/invoke to
[DllImport("indexfile")]
private static extern IntPtr openIndex(string pathname);

const int RTLD_NOW = 2; // for dlopen's flags
const int RTLD_GLOBAL = 8;

// its okay to have imports for the wrong platforms here
// because nothing will complain until I try to use the
// function
[DllImport("libdl.so")]
static extern IntPtr dlopen(string filename, int flags);

[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string filename);


static IndexFile()
{
    string libName = "";

    if (IsLinux)
        libName += "libindexfile.so";
    else
        libName += "indexfile.dll";

    // [snip] -- save embedded resource to temp dir

    IntPtr handle = IntPtr.Zero;

    if (IsLinux)
        handle = dlopen(libPath, RTLD_NOW|RTLD_GLOBAL);
    else
        handle = LoadLibrary(libPath);

    if (handle == IntPtr.Zero)
        throw new InvalidOperationException("Couldn't load the unmanaged library");
}


public IndexFile(String path)
{
    // P/Invoke to the unmanaged function
    // currently on Linux this throws a DllNotFoundException
    // works on Windows
    IntPtr ptr = openIndex(path);
}

Update:

It would appear that subsequent calls to LoadLibrary on windows look to see if a dll of the same name has already been loaded, and then uses that path. For example, in the following code, both calls to LoadLibrary will return a valid handle:

int _tmain(int argc, _TCHAR* argv[])
{
    LPCTSTR libpath = L"D:\\some\\path\\to\\library.dll";

    HMODULE handle1 = LoadLibrary(libpath);
    printf("Handle: %x\n", handle1);

    HMODULE handle2 = LoadLibrary(L"library.dll");
    printf("Handle: %x\n", handle2);

    return 0;
}

If the same is attempted with dlopen on Linux, the second call will fail, as it doesn’t assume that a library with the same name will be at the same path. Is there any way round this?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T20:54:45+00:00Added an answer on June 14, 2026 at 8:54 pm

    After much searching and head-scratching, I’ve discovered a solution. Full control can be exercised over the P/Invoke process by using dynamic P/Invoke to tell the runtime exactly where to find the code.


    Edit:

    Windows solution

    You need these imports:

    [DllImport("kernel32.dll")]
    protected static extern IntPtr LoadLibrary(string filename);
    
    [DllImport("kernel32.dll")]
    protected static extern IntPtr GetProcAddress(IntPtr hModule, string procname);
    

    The unmanaged library should be loaded by calling LoadLibrary:

    IntPtr moduleHandle = LoadLibrary("path/to/library.dll");
    

    Get a pointer to a function in the dll by calling GetProcAddress:

    IntPtr ptr = GetProcAddress(moduleHandle, methodName);
    

    Cast this ptr to a delegate of type TDelegate:

    TDelegate func = Marshal.GetDelegateForFunctionPointer(
        ptr, typeof(TDelegate)) as TDelegate;
    

    Linux Solution

    Use these imports:

    [DllImport("libdl.so")]
    protected static extern IntPtr dlopen(string filename, int flags);
    
    [DllImport("libdl.so")]
    protected static extern IntPtr dlsym(IntPtr handle, string symbol);
    
    const int RTLD_NOW = 2; // for dlopen's flags 
    

    Load the library:

    IntPtr moduleHandle = dlopen(modulePath, RTLD_NOW);
    

    Get the function pointer:

    IntPtr ptr = dlsym(moduleHandle, methodName);
    

    Cast it to a delegate as before:

    TDelegate func = Marshal.GetDelegateForFunctionPointer(
        ptr, typeof(TDelegate)) as TDelegate;
    

    For a helper library that I wrote, see my GitHub.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am doing a simple coin flipping experiment for class that involves flipping a
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
For some reason, after submitting a string like this Jack’s Spindle from a text
I'm trying to convert HTML to plain text. I get many &\#8217; &\#8220; etc.
I've got a string that has curly quotes in it. I'd like to replace
I have a small JavaScript validation script that validates inputs based on Regex. I

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.