非托管DLL的相对路径

可能重复:
在.NET中指定DllImport的搜索路径

我有一个非托管DLL。 对于清除,它是一个我想在我的C#代码中使用的C ++ dll。 问题是,它的Windows应用程序和用户可以安装在他们选择的任何目录。 所以我不能用静态路径来引用它,而且我也找不到一个给出相对路径的方法。 这是我尝试的代码:

 [DllImport("mydll.dll", CharSet = CharSet.Auto, SetLastError = true)]
  static extern bool SetDllDirectory(string lpPathName);

  public void SetDllDirectory(string lpPathName)
        {
            try
            {
                bool r = SetDllDirectory(lpPathName);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void SetDirectoryPath()
        {
            try
            {
                DirectoryInfo directory = new DirectoryInfo(System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath));
                if (directory.Exists)
                    SetDllDirectory(directory.ToString() + "mydll.dll");

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

以下是我收到的错误。

无法在DLL“mydll.dll”中找到名为“SetDllDirectory”的入口点。

这个问题可能是一个复制品

“c#中的C ++非托管DLL”

“平台调用声明中DLL的相对路径”

对不起,但我没有在这些参考文献中找到任何解决方案。


此错误消息:

无法在DLL“mydll.dll”中找到名为“SetDllDirectory”的入口点。

没有提到无法找到DLL。 它说你的P / Invoke定义不正确。 在DLL( mydll.dll )中没有名为SetDllDirectory函数。 为什么要这样呢? 从DLL中导出的唯一函数是您明确编码和导出的函数。 由于您没有为SetDllDirectory编写代码,并指出它应该从mydll.dll导出,因此它不存在于DLL中。

除此之外,这个问题是无法回答的,除非你用真实的代码更新你的问题。 您至少需要发布您试图从非托管DLL调用的函数的签名,以及您在C#(托管)端尝试过的P / Invoke代码。

问题是,它的Windows应用程序和用户可以安装在他们选择的任何目录。 所以我不能用静态路径来引用它,而且我也找不到一个给出相对路径的方法。

这不是一个真正的问题。 相对路径工作得很好,它们的工作方式与您的问题表明您已经尝试过的方式完全相同。 您只需在P / Invoke定义中包含DLL的名称。 默认的DLL搜索顺序负责其他所有操作。 如果托管的EXE与您要P / Invoke的非托管DLL位于同一目录中,则所有内容都可以无缝工作。

用户选择安装应用程序的位置并不重要,只要DLL和EXE位于同一文件夹中即可。 这就是你的安装程序的工作。

只要你使用相对路径,你绝对不需要使用Win32 API中的SetDllDirectory函数(它实际上是在kernel32.dll定义的)。


如果您试图拼凑到非标准位置的非托管库中,则需要将此位置添加到Windows用于查找dll文件的dll搜索路径中。

如果您的用户可以告诉程序c / c ++库文件的位置,您可以在选择它时手动加载它。

public class UnsafeNativeMethods {
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool SetDllDirectory(string lpPathName);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int GetDllDirectory(int bufsize, StringBuilder buf);

    [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern IntPtr LoadLibrary(string librayName);

    [DllImport("mylibrary")]
    public static extern void InitMyLibrary();
}

您可以使用某种形式的预加载程序调用上述程序,如下所示:

public void LoadDllFile( string dllfolder, string libname ) {
    var currentpath = new StringBuilder(255);
    UnsafeNativeMethods.GetDllDirectory( currentpath.Length, currentpath );

    // use new path
    UnsafeNativeMethods.SetDllDirectory( dllfolder );

    UnsafeNativeMethods.LoadLibrary( libname );

    // restore old path
    UnsafeNativeMethods.SetDllDirectory( currentpath );
}

你可能会这样称呼它:

LoadDllFile( "c:whatever", "mylibrary.dll" );
链接地址: http://www.djcxy.com/p/44469.html

上一篇: Relative path to unmanaged DLL

下一篇: How to P/Invoke to a native dll from Metro?