首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非托管DLL的相对路径

非托管DLL的相对路径
EN

Stack Overflow用户
提问于 2012-02-13 07:25:47
回答 2查看 12.8K关注 0票数 5

可能重复:

Specify the search path for DllImport in .NET

我有一个非托管DLL。为了获得许可,它是我想在我的C++代码中使用的c# dll。问题是它是一个windows应用程序,用户可以在他们选择的任何目录中安装它。所以我不能用静态路径来引用它,也找不到给出相对路径的方法。下面是我尝试过的代码:

代码语言:javascript
复制
 [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++ unmanaged DLL in c#

"Relative Path to DLL in Platform Invoke Statement

很抱歉,但我在这些参考资料中没有找到任何解决办法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-13 08:53:25

此错误消息:

无法在DLL 'mydll.dll‘中找到名为'SetDllDirectory’的入口点。

不知道不能找到DLL。它说您的P/Invoke定义不正确。在DLL (mydll.dll)中没有名为mydll.dll的函数。为什么会有呢?从DLL导出的唯一函数是显式编码和导出的函数。因为您没有为SetDllDirectory编写代码,并且指示应该从mydll.dll导出它,所以它不存在于DLL中。

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

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

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

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

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

票数 1
EN

Stack Overflow用户

发布于 2012-02-13 07:49:48

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

如果您的用户能够告诉程序c/c++库文件在哪里,您可以在他们选择它时手动加载它。

代码语言:javascript
复制
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();
}

您可以在某种形式的预加载例程中调用上面的内容,如下所示:

代码语言:javascript
复制
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 );
}

然后你可以这样称呼它:

代码语言:javascript
复制
LoadDllFile( "c:\whatever", "mylibrary.dll" );
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9256901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档